[PATCH v6 19/23] Kbuild: add Rust support
Having all the new files in place, we now enable Rust support in the build system, including `Kconfig` entries related to Rust, the Rust configuration printer, the target specification generation script, the version detection script and a few other bits. Co-developed-by: Alex Gaynor Signed-off-by: Alex Gaynor Co-developed-by: Finn Behrens Signed-off-by: Finn Behrens Co-developed-by: Adam Bratschi-Kaye Signed-off-by: Adam Bratschi-Kaye Co-developed-by: Wedson Almeida Filho Signed-off-by: Wedson Almeida Filho Co-developed-by: Michael Ellerman Signed-off-by: Michael Ellerman Co-developed-by: Sven Van Asbroeck Signed-off-by: Sven Van Asbroeck Co-developed-by: Gary Guo Signed-off-by: Gary Guo Co-developed-by: Boris-Chengbiao Zhou Signed-off-by: Boris-Chengbiao Zhou Co-developed-by: Boqun Feng Signed-off-by: Boqun Feng Co-developed-by: Douglas Su Signed-off-by: Douglas Su Co-developed-by: Dariusz Sosnowski Signed-off-by: Dariusz Sosnowski Co-developed-by: Antonio Terceiro Signed-off-by: Antonio Terceiro Co-developed-by: Daniel Xu Signed-off-by: Daniel Xu Co-developed-by: Miguel Cano Signed-off-by: Miguel Cano Signed-off-by: Miguel Ojeda --- .gitignore | 5 + .rustfmt.toml| 12 + Makefile | 175 +++- arch/Kconfig | 6 + arch/arm/Kconfig | 1 + arch/arm64/Kconfig | 1 + arch/powerpc/Kconfig | 1 + arch/riscv/Kconfig | 1 + arch/riscv/Makefile | 5 + arch/x86/Kconfig | 1 + arch/x86/Makefile| 14 + init/Kconfig | 45 ++- lib/Kconfig.debug| 155 rust/.gitignore | 10 + rust/Makefile| 397 +++ rust/bindgen_parameters | 17 + scripts/.gitignore | 1 + scripts/Kconfig.include | 6 +- scripts/Makefile | 3 + scripts/Makefile.build | 60 +++ scripts/Makefile.debug | 10 + scripts/Makefile.host| 34 +- scripts/Makefile.lib | 12 + scripts/Makefile.modfinal| 8 +- scripts/cc-version.sh| 12 +- scripts/generate_rust_target.rs | 227 +++ scripts/is_rust_module.sh| 13 + scripts/kconfig/confdata.c | 75 scripts/min-tool-version.sh | 6 + scripts/rust-is-available-bindgen-libclang.h | 2 + scripts/rust-is-available.sh | 158 31 files changed, 1450 insertions(+), 23 deletions(-) create mode 100644 .rustfmt.toml create mode 100644 rust/.gitignore create mode 100644 rust/Makefile create mode 100644 rust/bindgen_parameters create mode 100644 scripts/generate_rust_target.rs create mode 100755 scripts/is_rust_module.sh create mode 100644 scripts/rust-is-available-bindgen-libclang.h create mode 100755 scripts/rust-is-available.sh diff --git a/.gitignore b/.gitignore index 7afd412dadd2..48c68948f476 100644 --- a/.gitignore +++ b/.gitignore @@ -37,6 +37,7 @@ *.o *.o.* *.patch +*.rmeta *.s *.so *.so.dbg @@ -96,6 +97,7 @@ modules.order !.gitattributes !.gitignore !.mailmap +!.rustfmt.toml # # Generated include files @@ -161,3 +163,6 @@ x509.genkey # Documentation toolchain sphinx_*/ + +# Rust analyzer configuration +/rust-project.json diff --git a/.rustfmt.toml b/.rustfmt.toml new file mode 100644 index ..3de5cc497465 --- /dev/null +++ b/.rustfmt.toml @@ -0,0 +1,12 @@ +edition = "2021" +newline_style = "Unix" + +# Unstable options that help catching some mistakes in formatting and that we may want to enable +# when they become stable. +# +# They are kept here since they are useful to run from time to time. +#format_code_in_doc_comments = true +#reorder_impl_items = true +#comment_width = 100 +#wrap_comments = true +#normalize_comments = true diff --git a/Makefile b/Makefile index 9a820c525b86..d0837a13e9d3 100644 --- a/Makefile +++ b/Makefile @@ -120,6 +120,15 @@ endif export KBUILD_CHECKSRC +# Enable "clippy" (a linter) as part of the Rust compilation. +# +# Use 'make CLIPPY=1' to enable it. +ifeq ("$(origin CLIPPY)", "command line") + KBUILD_CLIPPY := $(CLIPPY) +endif + +export KBUILD_CLIPPY + # Use make M=dir or set the environment variable KBUILD_EXTMOD to specify the # directory of external module to build. Setting M= takes precedence. ifeq ("$(origin M)", "command line") @@ -267,7 +276,7 @@ no-dot-config-targets := $(clean-targets) \ cscope gtags TAGS tags help% %docs check% coccicheck \
Re: [PATCH] crypto: vmx - Align the short log with Makefile cleanups
On Sat, May 7, 2022 at 11:02 AM Herbert Xu wrote: > > On Sat, May 07, 2022 at 12:25:32AM +0900, Masahiro Yamada wrote: > > > > Sorry, I just noticed the 0day bot had reported the error. > > > > I sent v2.(CONFIG_LITTLE_ENDIAN --> CONFIG_CPU_LITTLE_ENDIAN) > > > > https://lore.kernel.org/lkml/20220506150820.1310802-1-masahi...@kernel.org/ > > > > > > Could you replace it, or fix it up, please? > > Please send me an incremental patch. Done. BTW, you added a wrong Reported-by tag: https://git.kernel.org/pub/scm/linux/kernel/git/herbert/cryptodev-2.6.git/commit/?id=b52455a73db95ef90fd3c2be84db77b55be43f46 It is a clean up patch, where 0day bot did not report anything. -- Best Regards Masahiro Yamada
[PATCH v6 00/23] Rust support
Rust support This is the patch series (v6) to add support for Rust as a second language to the Linux kernel. If you are interested in following this effort, please join us in the mailing list at: rust-for-li...@vger.kernel.org and take a look at the project itself at: https://github.com/Rust-for-Linux As usual, special thanks go to ISRG (Internet Security Research Group) and Google for their financial support on this endeavor. Cheers, Miguel -- # Rust support This cover letter explains the major changes and updates done since the previous ones. For those, please see: RFC: https://lore.kernel.org/lkml/20210414184604.23473-1-oj...@kernel.org/ v1: https://lore.kernel.org/lkml/20210704202756.29107-1-oj...@kernel.org/ v2: https://lore.kernel.org/lkml/20211206140313.5653-1-oj...@kernel.org/ v3: https://lore.kernel.org/lkml/20220117053349.6804-1-oj...@kernel.org/ v4: https://lore.kernel.org/lkml/20220212130410.6901-1-oj...@kernel.org/ v5: https://lore.kernel.org/lkml/20220317181032.15436-1-oj...@kernel.org/ ## Infrastructure updates There have been several improvements to the overall Rust support: - The toolchain and `alloc` have been upgraded to Rust 1.60.0. This version stabilized `feature(maybe_uninit_extra)` that we are using. - Support running documentation tests in-kernel, based on KUnit. Rust documentation tests are typically examples of usage of any item (e.g. function, struct, module...). They are very convenient because they are just written alongside the documentation, e.g.: /// Sums two numbers. /// /// # Examples /// /// ``` /// assert_eq!(mymod::f(10, 20), 30); /// ``` pub fn f(a: i32, b: i32) -> i32 { a + b } So far, we were compiling and running them in the host as any other Rust documentation test. However, that meant we could not run tests that used kernel APIs (though we were compile-testing them, which was already useful to keep the documentation in sync with the code). Now, the documentation tests for the `kernel` crate are transformed into a KUnit test suite during compilation and run within the kernel at boot time, if enabled. This means now we can run the tests that use kernel APIs. They look like this (their name is generated by `rustdoc`, based on the file and line): [0.581961] TAP version 14 [0.582092] 1..1 [0.582267] # Subtest: rust_kernel_doctests [0.582358] 1..70 [0.583626] ok 1 - rust_kernel_doctest_build_assert_rs_12_0 [0.584579] ok 2 - rust_kernel_doctest_build_assert_rs_55_0 [0.587357] ok 3 - rust_kernel_doctest_device_rs_361_0 [0.588037] ok 4 - rust_kernel_doctest_device_rs_386_0 ... [0.659249] ok 69 - rust_kernel_doctest_types_rs_445_0 [0.660451] ok 70 - rust_kernel_doctest_types_rs_509_0 [0.660680] # rust_kernel_doctests: pass:70 fail:0 skip:0 total:70 [0.660894] # Totals: pass:70 fail:0 skip:0 total:70 [0.661135] ok 1 - rust_kernel_doctests There are other benefits from this, such as being able to remove unneeded wrapper functions (that were used to avoid running some tests) as well as ensuring test code would actually compile within the kernel (e.g. `alloc` used different `cfg`s). - Tests are now (and are enforced to be) Clippy-clean, like the rest of the Rust kernel code (i.e. according to the same rules). - Other cleanups, fixes and improvements. ## Abstractions and driver updates Some of the improvements to the abstractions and example drivers are: - The start of networking support (`net` module), with types like: + `Namespace` (based on `struct net`). + `SkBuff` (based on `struct sk_buff`). + `Ipv4Addr` (based on `struct in_addr`), and its v6 equivalent. + `SocketAddrV4` (based on `struct sockaddr_in`), and its v6 equivalent. + `TcpListener` and `TcpStream` (based on `struct socket`). - The beginning of `async` support (`kasync` module). Rust provides support for asynchronous programming in a way that can be used in constrained environments, including the kernel. For instance, this allows us to write asynchronous TCP socket code within the kernel such as: async fn echo_server(stream: TcpStream) -> Result { let mut buf = [0u8; 1024]; loop { let n = stream.read( buf).await?; if n == 0 { return Ok(()); } stream.write_all([..n]).await?; } } This code looks very close to a synchronous version, yet it supports being driven to completion "step by step" by an executor. The `read()`/`write_all()` calls above, instead of blocking the current thread,
[PATCH] crypto: vmx - Fix build error
When I refactored this Makefile, I accidentally changed the CONFIG option. Fixes: b52455a73db9 ("crypto: vmx - Align the short log with Makefile cleanups") Reported-by: kernel test robot Signed-off-by: Masahiro Yamada --- drivers/crypto/vmx/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/crypto/vmx/Makefile b/drivers/crypto/vmx/Makefile index df93ba63b1cd..2560cfea1dec 100644 --- a/drivers/crypto/vmx/Makefile +++ b/drivers/crypto/vmx/Makefile @@ -3,7 +3,7 @@ obj-$(CONFIG_CRYPTO_DEV_VMX_ENCRYPT) += vmx-crypto.o vmx-crypto-objs := vmx.o aesp8-ppc.o ghashp8-ppc.o aes.o aes_cbc.o aes_ctr.o aes_xts.o ghash.o quiet_cmd_perl = PERL$@ - cmd_perl = $(PERL) $< $(if $(CONFIG_LITTLE_ENDIAN), linux-ppc64le, linux-ppc64) > $@ + cmd_perl = $(PERL) $< $(if $(CONFIG_CPU_LITTLE_ENDIAN), linux-ppc64le, linux-ppc64) > $@ targets += aesp8-ppc.S ghashp8-ppc.S -- 2.32.0
Re: [PATCH 2/3] mm: rmap: Fix CONT-PTE/PMD size hugetlb issue when migration
On 5/7/2022 1:56 AM, Mike Kravetz wrote: On 5/5/22 20:39, Baolin Wang wrote: On 5/6/2022 7:53 AM, Mike Kravetz wrote: On 4/29/22 01:14, Baolin Wang wrote: On some architectures (like ARM64), it can support CONT-PTE/PMD size hugetlb, which means it can support not only PMD/PUD size hugetlb: 2M and 1G, but also CONT-PTE/PMD size: 64K and 32M if a 4K page size specified. diff --git a/mm/rmap.c b/mm/rmap.c index 6fdd198..7cf2408 100644 --- a/mm/rmap.c +++ b/mm/rmap.c @@ -1924,13 +1924,15 @@ static bool try_to_migrate_one(struct folio *folio, struct vm_area_struct *vma, break; } } + + /* Nuke the hugetlb page table entry */ + pteval = huge_ptep_clear_flush(vma, address, pvmw.pte); } else { flush_cache_page(vma, address, pte_pfn(*pvmw.pte)); + /* Nuke the page table entry. */ + pteval = ptep_clear_flush(vma, address, pvmw.pte); } On arm64 with CONT-PTE/PMD the returned pteval will have dirty or young set if ANY of the PTE/PMDs had dirty or young set. Right. - /* Nuke the page table entry. */ - pteval = ptep_clear_flush(vma, address, pvmw.pte); - /* Set the dirty flag on the folio now the pte is gone. */ if (pte_dirty(pteval)) folio_mark_dirty(folio); @@ -2015,7 +2017,10 @@ static bool try_to_migrate_one(struct folio *folio, struct vm_area_struct *vma, pte_t swp_pte; if (arch_unmap_one(mm, vma, address, pteval) < 0) { - set_pte_at(mm, address, pvmw.pte, pteval); + if (folio_test_hugetlb(folio)) + set_huge_pte_at(mm, address, pvmw.pte, pteval); And, we will use that pteval for ALL the PTE/PMDs here. So, we would set the dirty or young bit in ALL PTE/PMDs. Could that cause any issues? May be more of a question for the arm64 people. I don't think this will cause any issues. Since the hugetlb can not be split, and we should not lose the the dirty or young state if any subpages were set. Meanwhile we already did like this in hugetlb.c: pte = huge_ptep_get_and_clear(mm, address, ptep); tlb_remove_huge_tlb_entry(h, tlb, ptep, address); if (huge_pte_dirty(pte)) set_page_dirty(page); Agree that it 'should not' cause issues. It just seems inconsistent. This is not a problem specifically with your patch, just the handling of CONT-PTE/PMD entries. There does not appear to be an arm64 specific version of huge_ptep_get() that takes CONT-PTE/PMD into account. So, huge_ptep_get() would only return the one specific value. It would not take into account the dirty or young bits of CONT-PTE/PMDs like your new version of huge_ptep_get_and_clear. Is that correct? Or, am I missing something. Yes, you are right. If I am correct, then code like the following may not work: static int gather_hugetlb_stats(pte_t *pte, unsigned long hmask, unsigned long addr, unsigned long end, struct mm_walk *walk) { pte_t huge_pte = huge_ptep_get(pte); struct numa_maps *md; struct page *page; if (!pte_present(huge_pte)) return 0; page = pte_page(huge_pte); md = walk->private; gather_stats(page, md, pte_dirty(huge_pte), 1); return 0; } Right, this is inconsistent with current huge_ptep_get() interface like you said. So I think we can define an ARCH-specific huge_ptep_get() interface for arm64, and some sample code like below. How do you think? +pte_t huge_ptep_get(pte_t *ptep, unsigned long size) +{ + int ncontig; + pte_t orig_pte = ptep_get(ptep); + + if (!pte_cont(orig_pte)) + return orig_pte; + + switch (size) { + case CONT_PMD_SIZE: + ncontig = CONT_PMDS; + break; + case CONT_PTE_SIZE: + ncontig = CONT_PTES; + break; + default: + WARN_ON_ONCE(1); + return orig_pte; + } + + for (i = 0; i < ncontig; i++, ptep++) { + pte_t pte = ptep_get(ptep); + + if (pte_dirty(pte)) + orig_pte = pte_mkdirty(orig_pte); + + if (pte_young(pte)) + orig_pte = pte_mkyong(orig_pte); + } + + return orig_pte; +}
Re: [PATCH] crypto: vmx - Align the short log with Makefile cleanups
On Sat, May 07, 2022 at 12:25:32AM +0900, Masahiro Yamada wrote: > > Sorry, I just noticed the 0day bot had reported the error. > > I sent v2.(CONFIG_LITTLE_ENDIAN --> CONFIG_CPU_LITTLE_ENDIAN) > > https://lore.kernel.org/lkml/20220506150820.1310802-1-masahi...@kernel.org/ > > > Could you replace it, or fix it up, please? Please send me an incremental patch. Thanks, -- Email: Herbert Xu Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
Re: [PATCH 3/3] mm: rmap: Fix CONT-PTE/PMD size hugetlb issue when unmapping
On 5/7/2022 2:55 AM, Mike Kravetz wrote: On 4/29/22 01:14, Baolin Wang wrote: On some architectures (like ARM64), it can support CONT-PTE/PMD size hugetlb, which means it can support not only PMD/PUD size hugetlb: 2M and 1G, but also CONT-PTE/PMD size: 64K and 32M if a 4K page size specified. When unmapping a hugetlb page, we will get the relevant page table entry by huge_pte_offset() only once to nuke it. This is correct for PMD or PUD size hugetlb, since they always contain only one pmd entry or pud entry in the page table. However this is incorrect for CONT-PTE and CONT-PMD size hugetlb, since they can contain several continuous pte or pmd entry with same page table attributes, so we will nuke only one pte or pmd entry for this CONT-PTE/PMD size hugetlb page. And now we only use try_to_unmap() to unmap a poisoned hugetlb page, Since try_to_unmap can be called for non-hugetlb pages, perhaps the following is more accurate? try_to_unmap is only passed a hugetlb page in the case where the hugetlb page is poisoned. Yes, will update in next version. It does concern me that this assumption is built into the code as pointed out in your discussion with Gerald. Should we perhaps add a VM_BUG_ON() to make sure the passed huge page is poisoned? This would be in the same 'if block' where we call adjust_range_if_pmd_sharing_possible. Good point. Will do in next version. Thanks.
Re: [RFC v2 01/39] Kconfig: introduce HAS_IOPORT option and select it as necessary
On Fri, 6 May 2022, Niklas Schnelle wrote: > On Fri, 2022-05-06 at 19:12 +1000, Finn Thain wrote: > > > > On Thu, 5 May 2022, Bjorn Helgaas wrote: > > > > > On Thu, May 05, 2022 at 07:39:42PM +0200, Arnd Bergmann wrote: > > > > On Thu, May 5, 2022 at 6:10 PM Bjorn Helgaas wrote: > > > > > On Wed, May 04, 2022 at 11:31:28PM +0200, Arnd Bergmann wrote: > > > > > > The main goal is to avoid c), which is what happens on s390, > > > > > > but can also happen elsewhere. Catching b) would be nice as > > > > > > well, but is much harder to do from generic code as you'd need > > > > > > an architecture specific inline asm statement to insert a > > > > > > ex_table fixup, or a runtime conditional on each access. > > > > > > > > > > Or s390 could implement its own inb(). > > > > > > > > > > I'm hearing that generic powerpc kernels have to run both on > > > > > machines that have I/O port space and those that don't. That > > > > > makes me think s390 could do something similar. > > > > > > > > No, this is actually the current situation, and it makes > > > > absolutely no sense. s390 has no way of implementing inb()/outb() > > > > because there are no instructions for it and it cannot tunnel them > > > > through a virtual address mapping like on most of the other > > > > architectures. (it has special instructions for accessing memory > > > > space, which is not the same as a pointer dereference here). > > > > > > > > The existing implementation gets flagged as a NULL pointer > > > > dereference by a compiler warning because it effectively is. > > > > > > I think s390 currently uses the inb() in asm-generic/io.h, i.e., > > > "__raw_readb(PCI_IOBASE + addr)". I understand that's a NULL > > > pointer dereference because the default PCI_IOBASE is 0. > > > > > > I mooted a s390 inb() implementation like "return ~0" because that's > > > what happens on most arches when there's no device to respond to the > > > inb(). > > > > > > The HAS_IOPORT dependencies are fairly ugly IMHO, and they clutter > > > drivers that use I/O ports in some cases but not others. But maybe > > > it's the most practical way. > > > > > > > Do you mean, "the most practical way to avoid a compiler warning on > > s390"? What about "#pragma GCC diagnostic ignored"? > > This actually happens with clang. That suggests a clang bug to me. If you believe GCC should behave like clang, then I guess the pragma above really is the one you want. If you somehow feel that the kernel should cater to gcc and clang even where they disagree then you would have to use "#pragma clang diagnostic ignored". > Apart from that, I think this would also fall under the same argument as > the original patch Linus unpulled. We would just paint over someting > that we know at compile time won't work: > > https://lore.kernel.org/lkml/CAHk-=wg80je=k7madf4e7wrrnp37e3qh6y10svhdc7o8sz_...@mail.gmail.com/ > I wasn't advocating adding any warnings. If you know at compile time that a driver won't work, the usual solution is scripts/config -d CONFIG_SOME_UNDESIRED_DRIVER. Why is that no longer appropriate for drivers that use IO ports?
Re: [PATCH v3 00/15] kbuild: yet another series of cleanups (modpost, LTO, MODULE_REL_CRCS)
Hi Masahiro, On Thu, May 05, 2022 at 04:22:29PM +0900, Masahiro Yamada wrote: > > This is the third batch of cleanups in this development cycle. > > Major changes in v3: > > - Generate symbol CRCs as C code, and remove CONFIG_MODULE_REL_CRCS. > > Major changes in v2: > > - V1 did not work with CONFIG_MODULE_REL_CRCS. >I fixed this for v2. > > - Reflect some review comments in v1 > > - Refactor the code more > > - Avoid too long argument error > > > Masahiro Yamada (15): > modpost: mitigate false-negatives for static EXPORT_SYMBOL checks > modpost: change the license of EXPORT_SYMBOL to bool type > modpost: merge add_{intree_flag,retpoline,staging_flag} to add_header > modpost: move *.mod.c generation to write_mod_c_files() > kbuild: generate a list of objects in vmlinux > kbuild: record symbol versions in *.cmd files > modpost: extract symbol versions from *.cmd files > kbuild: link symbol CRCs at final link, removing > CONFIG_MODULE_REL_CRCS > kbuild: stop merging *.symversions > genksyms: adjust the output format to modpost > kbuild: do not create *.prelink.o for Clang LTO or IBT > modpost: simplify the ->is_static initialization > modpost: use hlist for hash table implementation > kbuild: make built-in.a rule robust against too long argument error > kbuild: make *.mod rule robust against too long argument error I merged this series into mainline and tested an Arch Linux x86_64 configuration and Fedora aarch64 configuration with ThinLTO and saw no new warnings or issues. Modules loaded just fine in QEMU for Arch Linux and I did not notice any boot issues or warnings. Tested-by: Nathan Chancellor Cheers, Nathan
Re: [PATCH v6 15/29] x86/hpet: Add helper function hpet_set_comparator_periodic()
On Fri, May 06 2022 at 23:41, Thomas Gleixner wrote: > On Thu, May 05 2022 at 16:59, Ricardo Neri wrote: >> Programming an HPET channel as periodic requires setting the >> HPET_TN_SETVAL bit in the channel configuration. Plus, the comparator >> register must be written twice (once for the comparator value and once for >> the periodic value). Since this programming might be needed in several >> places (e.g., the HPET clocksource and the HPET-based hardlockup detector), >> add a helper function for this purpose. >> >> A helper function hpet_set_comparator_oneshot() could also be implemented. >> However, such function would only program the comparator register and the >> function would be quite small. Hence, it is better to not bloat the code >> with such an obvious function. > > This word salad above does not provide a single reason why the periodic > programming function is required and better suited for the NMI watchdog > case and then goes on and blurbs about why a function which is not > required is not implemented. The argument about not bloating the code > with an "obvious???" function which is quite small is slightly beyond my > comprehension level. What's even more uncomprehensible is that the patch which actually sets up that NMI watchdog cruft has: > + if (hc->boot_cfg & HPET_TN_PERIODIC_CAP) > + hld_data->has_periodic = true; So how the heck does that work with a HPET which does not support periodic mode? That watchdog muck will still happily invoke that set periodic function in the hope that it works by chance? Thanks, tglx
Re: [PATCH v6 15/29] x86/hpet: Add helper function hpet_set_comparator_periodic()
On Thu, May 05 2022 at 16:59, Ricardo Neri wrote: > Programming an HPET channel as periodic requires setting the > HPET_TN_SETVAL bit in the channel configuration. Plus, the comparator > register must be written twice (once for the comparator value and once for > the periodic value). Since this programming might be needed in several > places (e.g., the HPET clocksource and the HPET-based hardlockup detector), > add a helper function for this purpose. > > A helper function hpet_set_comparator_oneshot() could also be implemented. > However, such function would only program the comparator register and the > function would be quite small. Hence, it is better to not bloat the code > with such an obvious function. This word salad above does not provide a single reason why the periodic programming function is required and better suited for the NMI watchdog case and then goes on and blurbs about why a function which is not required is not implemented. The argument about not bloating the code with an "obvious???" function which is quite small is slightly beyond my comprehension level. Thanks, tglx
Re: [PATCH v6 13/29] iommu/amd: Compose MSI messages for NMI irqs in non-IR format
On Thu, May 05 2022 at 16:59, Ricardo Neri wrote: > + * > + * Also, NMIs do not have an associated vector. No need for cleanup. They have a vector and what the heck is this cleanup comment for here? There is nothing cleanup alike anywhere near. Adding confusing comments is worse than adding no comments at all. Thanks, tglx
Re: [PATCH v6 12/29] iommu/amd: Enable NMIPass when allocating an NMI irq
On Thu, May 05 2022 at 16:59, Ricardo Neri wrote: > > + if (info->flags & X86_IRQ_ALLOC_AS_NMI) { > + /* Only one IRQ per NMI */ > + if (nr_irqs != 1) > + return -EINVAL; See previous reply.
Re: [PATCH v6 10/29] iommu/vt-d: Implement minor tweaks for NMI irqs
On Thu, May 05 2022 at 16:59, Ricardo Neri wrote: > The Intel IOMMU interrupt remapping driver already programs correctly the > delivery mode of individual irqs as per their irq_data. Improve handling > of NMIs. Allow only one irq per NMI. Also, it is not necessary to cleanup > irq vectors after updating affinity. Structuring a changelog in paragraphs might make it readable. New lines exist for a reason. > NMIs do not have associated vectors. Again. NMI has an vector associated, but it is not subject to dynamic vector management. > diff --git a/drivers/iommu/intel/irq_remapping.c > b/drivers/iommu/intel/irq_remapping.c > index fb2d71bea98d..791a9331e257 100644 > --- a/drivers/iommu/intel/irq_remapping.c > +++ b/drivers/iommu/intel/irq_remapping.c > @@ -1198,8 +1198,12 @@ intel_ir_set_affinity(struct irq_data *data, const > struct cpumask *mask, >* After this point, all the interrupts will start arriving >* at the new destination. So, time to cleanup the previous >* vector allocation. > + * > + * Do it only for non-NMI irqs. NMIs don't have associated > + * vectors. See above. >*/ > - send_cleanup_vector(cfg); > + if (cfg->delivery_mode != APIC_DELIVERY_MODE_NMI) > + send_cleanup_vector(cfg); So this needs to be replicated for all invocations of send_cleanup_vector(), right? Why can't you put it into that function? > return IRQ_SET_MASK_OK_DONE; > } > @@ -1352,6 +1356,9 @@ static int intel_irq_remapping_alloc(struct irq_domain > *domain, > if (info->type == X86_IRQ_ALLOC_TYPE_PCI_MSI) > info->flags &= ~X86_IRQ_ALLOC_CONTIGUOUS_VECTORS; > > + if ((info->flags & X86_IRQ_ALLOC_AS_NMI) && nr_irqs != 1) > + return -EINVAL; This cannot be reached when the vector allocation domain already rejected it, but copy & pasta is wonderful and increases the line count. Thanks, tglx
Re: [PATCH v6 05/29] x86/apic/vector: Do not allocate vectors for NMIs
On Thu, May 05 2022 at 16:59, Ricardo Neri wrote: > Vectors are meaningless when allocating IRQs with NMI as the delivery > mode. Vectors are not meaningless. NMI has a fixed vector. The point is that for a fixed vector there is no vector management required. Can you spot the difference? > In such case, skip the reservation of IRQ vectors. Do it in the lowest- > level functions where the actual IRQ reservation takes place. > > Since NMIs target specific CPUs, keep the functionality to find the best > CPU. Again. What for? > + if (apicd->hw_irq_cfg.delivery_mode == APIC_DELIVERY_MODE_NMI) { > + cpu = irq_matrix_find_best_cpu(vector_matrix, dest); > + apicd->cpu = cpu; > + vector = 0; > + goto no_vector; > + } Why would a NMI ever end up in this code? There is no vector management required and this find cpu exercise is pointless. > vector = irq_matrix_alloc(vector_matrix, dest, resvd, ); > trace_vector_alloc(irqd->irq, vector, resvd, vector); > if (vector < 0) > return vector; > apic_update_vector(irqd, vector, cpu); > + > +no_vector: > apic_update_irq_cfg(irqd, vector, cpu); > > return 0; > @@ -321,12 +330,22 @@ assign_managed_vector(struct irq_data *irqd, const > struct cpumask *dest) > /* set_affinity might call here for nothing */ > if (apicd->vector && cpumask_test_cpu(apicd->cpu, vector_searchmask)) > return 0; > + > + if (apicd->hw_irq_cfg.delivery_mode == APIC_DELIVERY_MODE_NMI) { > + cpu = irq_matrix_find_best_cpu_managed(vector_matrix, dest); > + apicd->cpu = cpu; > + vector = 0; > + goto no_vector; > + } This code can never be reached for a NMI delivery. If so, then it's a bug. This all is special purpose for that particular HPET NMI watchdog use case and we are not exposing this to anything else at all. So why are you sprinkling this NMI nonsense all over the place? Just because? There are well defined entry points to all of this where this can be fenced off. If at some day the hardware people get their act together and provide a proper vector space for NMIs then we have to revisit that, but then there will be a separate NMI vector management too. What you want is the below which also covers the next patch. Please keep an eye on the comments I added/modified. Thanks, tglx --- --- a/arch/x86/kernel/apic/vector.c +++ b/arch/x86/kernel/apic/vector.c @@ -42,6 +42,7 @@ EXPORT_SYMBOL_GPL(x86_vector_domain); static DEFINE_RAW_SPINLOCK(vector_lock); static cpumask_var_t vector_searchmask; static struct irq_chip lapic_controller; +static struct irq_chip lapic_nmi_controller; static struct irq_matrix *vector_matrix; #ifdef CONFIG_SMP static DEFINE_PER_CPU(struct hlist_head, cleanup_list); @@ -451,6 +452,10 @@ static int x86_vector_activate(struct ir trace_vector_activate(irqd->irq, apicd->is_managed, apicd->can_reserve, reserve); + /* NMI has a fixed vector. No vector management required */ + if (apicd->hw_irq_cfg.delivery_mode == APIC_DELIVERY_MODE_NMI) + return 0; + raw_spin_lock_irqsave(_lock, flags); if (!apicd->can_reserve && !apicd->is_managed) assign_irq_vector_any_locked(irqd); @@ -472,6 +477,10 @@ static void vector_free_reserved_and_man trace_vector_teardown(irqd->irq, apicd->is_managed, apicd->has_reserved); + /* NMI has a fixed vector. No vector management required */ + if (apicd->hw_irq_cfg.delivery_mode == APIC_DELIVERY_MODE_NMI) + return; + if (apicd->has_reserved) irq_matrix_remove_reserved(vector_matrix); if (apicd->is_managed) @@ -568,6 +577,24 @@ static int x86_vector_alloc_irqs(struct irqd->hwirq = virq + i; irqd_set_single_target(irqd); + if (info->flags & X86_IRQ_ALLOC_AS_NMI) { + /* +* NMIs have a fixed vector and need their own +* interrupt chip so nothing can end up in the +* regular local APIC management code except the +* MSI message composing callback. +*/ + irqd->chip = _nmi_controller; + /* +* Don't allow affinity setting attempts for NMIs. +* This cannot work with the regular affinity +* mechanisms and for the intended HPET NMI +* watchdog use case it's not required. +*/ + irqd_set_no_balance(irqd); + continue; + } + /* * Prevent that any of these interrupts is invoked in * non interrupt context via e.g.
[PATCH] powerpc/85xx: P2020: Add fsl,mpc8548-pmc node
P2020 also contains Power Management Controller and their registers at offset 0xe0070 compatible with mpc8548. So add PMC node into DTS include file fsl/p2020si-post.dtsi Signed-off-by: Pali Rohár --- arch/powerpc/boot/dts/fsl/p2020si-post.dtsi | 5 + 1 file changed, 5 insertions(+) diff --git a/arch/powerpc/boot/dts/fsl/p2020si-post.dtsi b/arch/powerpc/boot/dts/fsl/p2020si-post.dtsi index 6345629524fe..81b9ab2119be 100644 --- a/arch/powerpc/boot/dts/fsl/p2020si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/p2020si-post.dtsi @@ -201,4 +201,9 @@ reg = <0xe 0x1000>; fsl,has-rstcr; }; + + pmc: power@e0070 { + compatible = "fsl,mpc8548-pmc"; + reg = <0xe0070 0x20>; + }; }; -- 2.20.1
Re: [PATCH v6 03/29] x86/apic/msi: Set the delivery mode individually for each IRQ
On Thu, May 05 2022 at 16:59, Ricardo Neri wrote: > There are no restrictions in hardware to set MSI messages with its > own delivery mode. "messages with its own" ? Plural/singular confusion. > Use the mode specified in the provided IRQ hardware > configuration data. Since most of the IRQs are configured to use the > delivery mode of the APIC driver in use (set in all of them to > APIC_DELIVERY_MODE_FIXED), the only functional changes are where > IRQs are configured to use a specific delivery mode. This does not parse. There are no functional changes due to this patch and there is no point talking about functional changes in subsequent patches here. > Changing the utility function __irq_msi_compose_msg() takes care of > implementing the change in the in the local APIC, PCI-MSI, and DMAR-MSI in the in the > irq_chips. > > The IO-APIC irq_chip configures the entries in the interrupt redirection > table using the delivery mode specified in the corresponding MSI message. > Since the MSI message is composed by a higher irq_chip in the hierarchy, > it does not need to be updated. The point is that updating __irq_msi_compose_msg() covers _all_ MSI consumers including IO-APIC. I had to read that changelog 3 times to make sense of it. Something like this perhaps: "x86/apic/msi: Use the delivery mode from irq_cfg for message composition irq_cfg provides a delivery mode for each interrupt. Use it instead of the hardcoded APIC_DELIVERY_MODE_FIXED. This allows to compose messages for NMI delivery mode which is required to implement a HPET based NMI watchdog. No functional change as the default delivery mode is set to APIC_DELIVERY_MODE_FIXED." Thanks, tglx
Re: [PATCH v6 02/29] x86/apic: Add irq_cfg::delivery_mode
On Thu, May 05 2022 at 16:59, Ricardo Neri wrote: > Currently, the delivery mode of all interrupts is set to the mode of the > APIC driver in use. There are no restrictions in hardware to configure the > delivery mode of each interrupt individually. Also, certain IRQs need > to be s/IRQ/interrupt/ Changelogs can do without acronyms. > configured with a specific delivery mode (e.g., NMI). > > Add a new member, delivery_mode, to struct irq_cfg. Subsequent changesets > will update every irq_domain to set the delivery mode of each IRQ to that > specified in its irq_cfg data. > > To keep the current behavior, when allocating an IRQ in the root > domain The root domain does not allocate an interrupt. The root domain allocates a vector for an interrupt. There is a very clear and technical destinction. Can you please be more careful about the wording? > --- a/arch/x86/kernel/apic/vector.c > +++ b/arch/x86/kernel/apic/vector.c > @@ -567,6 +567,7 @@ static int x86_vector_alloc_irqs(struct irq_domain > *domain, unsigned int virq, > irqd->chip_data = apicd; > irqd->hwirq = virq + i; > irqd_set_single_target(irqd); > + Stray newline. > /* >* Prevent that any of these interrupts is invoked in >* non interrupt context via e.g. generic_handle_irq() > @@ -577,6 +578,14 @@ static int x86_vector_alloc_irqs(struct irq_domain > *domain, unsigned int virq, > /* Don't invoke affinity setter on deactivated interrupts */ > irqd_set_affinity_on_activate(irqd); > > + /* > + * Initialize the delivery mode of this irq to match the s/irq/interrupt/ > + * default delivery mode of the APIC. Children irq domains > + * may take the delivery mode from the individual irq > + * configuration rather than from the APIC driver. > + */ > + apicd->hw_irq_cfg.delivery_mode = apic->delivery_mode; > + > /* >* Legacy vectors are already assigned when the IOAPIC >* takes them over. They stay on the same vector. This is
Re: [PATCH v6 01/29] irq/matrix: Expose functions to allocate the best CPU for new vectors
Ricardo, On Thu, May 05 2022 at 16:59, Ricardo Neri wrote: > Certain types of interrupts, such as NMI, do not have an associated vector. > They, however, target specific CPUs. Thus, when assigning the destination > CPU, it is beneficial to select the one with the lowest number of > vectors. Why is that beneficial especially in the context of a NMI watchdog which then broadcasts the NMI to all other CPUs? That's wishful thinking perhaps, but I don't see any benefit at all. > Prepend the functions matrix_find_best_cpu_managed() and > matrix_find_best_cpu_managed() The same function prepended twice becomes two functions :) > with the irq_ prefix and expose them for > IRQ controllers to use when allocating and activating vector-less IRQs. There is no such thing like a vectorless IRQ. NMIs have a vector. Can we please describe facts and not pulled out of thin air concepts which do not exist? Thanks, tglx
Re: [PATCH 3/3] mm: rmap: Fix CONT-PTE/PMD size hugetlb issue when unmapping
On 5/3/22 03:03, Gerald Schaefer wrote: > On Tue, 3 May 2022 10:19:46 +0800 > Baolin Wang wrote: > >> >> >> On 5/2/2022 10:02 PM, Gerald Schaefer wrote: >>> On Sat, 30 Apr 2022 11:22:33 +0800 >>> Baolin Wang wrote: >>> On 4/30/2022 4:02 AM, Gerald Schaefer wrote: > On Fri, 29 Apr 2022 16:14:43 +0800 > Baolin Wang wrote: > >> On some architectures (like ARM64), it can support CONT-PTE/PMD size >> hugetlb, which means it can support not only PMD/PUD size hugetlb: >> 2M and 1G, but also CONT-PTE/PMD size: 64K and 32M if a 4K page >> size specified. >> >> When unmapping a hugetlb page, we will get the relevant page table >> entry by huge_pte_offset() only once to nuke it. This is correct >> for PMD or PUD size hugetlb, since they always contain only one >> pmd entry or pud entry in the page table. >> >> However this is incorrect for CONT-PTE and CONT-PMD size hugetlb, >> since they can contain several continuous pte or pmd entry with >> same page table attributes, so we will nuke only one pte or pmd >> entry for this CONT-PTE/PMD size hugetlb page. >> >> And now we only use try_to_unmap() to unmap a poisoned hugetlb page, >> which means now we will unmap only one pte entry for a CONT-PTE or >> CONT-PMD size poisoned hugetlb page, and we can still access other >> subpages of a CONT-PTE or CONT-PMD size poisoned hugetlb page, >> which will cause serious issues possibly. >> >> So we should change to use huge_ptep_clear_flush() to nuke the >> hugetlb page table to fix this issue, which already considered >> CONT-PTE and CONT-PMD size hugetlb. >> >> Note we've already used set_huge_swap_pte_at() to set a poisoned >> swap entry for a poisoned hugetlb page. >> >> Signed-off-by: Baolin Wang >> --- >>mm/rmap.c | 34 +- >>1 file changed, 17 insertions(+), 17 deletions(-) >> >> diff --git a/mm/rmap.c b/mm/rmap.c >> index 7cf2408..1e168d7 100644 >> --- a/mm/rmap.c >> +++ b/mm/rmap.c >> @@ -1564,28 +1564,28 @@ static bool try_to_unmap_one(struct folio >> *folio, struct vm_area_struct *vma, >> break; >> } >> } >> +pteval = huge_ptep_clear_flush(vma, address, >> pvmw.pte); > > Unlike in your patch 2/3, I do not see that this (huge) pteval would later > be used again with set_huge_pte_at() instead of set_pte_at(). Not sure if > this (huge) pteval could end up at a set_pte_at() later, but if yes, then > this would be broken on s390, and you'd need to use set_huge_pte_at() > instead of set_pte_at() like in your patch 2/3. IIUC, As I said in the commit message, we will only unmap a poisoned hugetlb page by try_to_unmap(), and the poisoned hugetlb page will be remapped with a poisoned entry by set_huge_swap_pte_at() in try_to_unmap_one(). So I think no need change to use set_huge_pte_at() instead of set_pte_at() for other cases, since the hugetlb page will not hit other cases. if (PageHWPoison(subpage) && !(flags & TTU_IGNORE_HWPOISON)) { pteval = swp_entry_to_pte(make_hwpoison_entry(subpage)); if (folio_test_hugetlb(folio)) { hugetlb_count_sub(folio_nr_pages(folio), mm); set_huge_swap_pte_at(mm, address, pvmw.pte, pteval, vma_mmu_pagesize(vma)); } else { dec_mm_counter(mm, mm_counter(>page)); set_pte_at(mm, address, pvmw.pte, pteval); } } >>> >>> OK, but wouldn't the pteval be overwritten here with >>> pteval = swp_entry_to_pte(make_hwpoison_entry(subpage))? >>> IOW, what sense does it make to save the returned pteval from >>> huge_ptep_clear_flush(), when it is never being used anywhere? >> >> Please see previous code, we'll use the original pte value to check if >> it is uffd-wp armed, and if need to mark it dirty though the hugetlbfs >> is set noop_dirty_folio(). >> >> pte_install_uffd_wp_if_needed(vma, address, pvmw.pte, pteval); > > Uh, ok, that wouldn't work on s390, but we also don't have > CONFIG_PTE_MARKER_UFFD_WP / HAVE_ARCH_USERFAULTFD_WP set, so > I guess we will be fine (for now). > > Still, I find it a bit unsettling that pte_install_uffd_wp_if_needed() > would work on a potential hugetlb *pte, directly de-referencing it > instead of using huge_ptep_get(). > > The !pte_none(*pte) check at the beginning would be broken in the > hugetlb case for s390 (not sure about other archs, but I think s390 > might be the only exception strictly requiring huge_ptep_get() > for de-referencing hugetlb *pte pointers). > Adding Peter Wu mostly for above as he is working uffd_wp. >> >> /* Set the dirty flag on the folio now the pte is gone. */ >> if
Re: [PATCH 3/3] mm: rmap: Fix CONT-PTE/PMD size hugetlb issue when unmapping
On 4/29/22 01:14, Baolin Wang wrote: > On some architectures (like ARM64), it can support CONT-PTE/PMD size > hugetlb, which means it can support not only PMD/PUD size hugetlb: > 2M and 1G, but also CONT-PTE/PMD size: 64K and 32M if a 4K page > size specified. > > When unmapping a hugetlb page, we will get the relevant page table > entry by huge_pte_offset() only once to nuke it. This is correct > for PMD or PUD size hugetlb, since they always contain only one > pmd entry or pud entry in the page table. > > However this is incorrect for CONT-PTE and CONT-PMD size hugetlb, > since they can contain several continuous pte or pmd entry with > same page table attributes, so we will nuke only one pte or pmd > entry for this CONT-PTE/PMD size hugetlb page. > > And now we only use try_to_unmap() to unmap a poisoned hugetlb page, Since try_to_unmap can be called for non-hugetlb pages, perhaps the following is more accurate? try_to_unmap is only passed a hugetlb page in the case where the hugetlb page is poisoned. It does concern me that this assumption is built into the code as pointed out in your discussion with Gerald. Should we perhaps add a VM_BUG_ON() to make sure the passed huge page is poisoned? This would be in the same 'if block' where we call adjust_range_if_pmd_sharing_possible. -- Mike Kravetz > which means now we will unmap only one pte entry for a CONT-PTE or > CONT-PMD size poisoned hugetlb page, and we can still access other > subpages of a CONT-PTE or CONT-PMD size poisoned hugetlb page, > which will cause serious issues possibly. > > So we should change to use huge_ptep_clear_flush() to nuke the > hugetlb page table to fix this issue, which already considered > CONT-PTE and CONT-PMD size hugetlb. > > Note we've already used set_huge_swap_pte_at() to set a poisoned > swap entry for a poisoned hugetlb page. > > Signed-off-by: Baolin Wang > --- > mm/rmap.c | 34 +- > 1 file changed, 17 insertions(+), 17 deletions(-)
[PATCH net-next 6/6] net: wan: switch to netif_napi_add_weight()
A handful of WAN drivers use custom napi weights, switch them to the new API. Signed-off-by: Jakub Kicinski --- CC: qiang.z...@nxp.com CC: k...@pm.waw.pl CC: m...@dev.tdt.de CC: linuxppc-dev@lists.ozlabs.org CC: linux-...@vger.kernel.org --- drivers/net/wan/fsl_ucc_hdlc.c | 2 +- drivers/net/wan/hd64572.c | 3 ++- drivers/net/wan/ixp4xx_hss.c | 2 +- drivers/net/wan/lapbether.c| 2 +- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/net/wan/fsl_ucc_hdlc.c b/drivers/net/wan/fsl_ucc_hdlc.c index 5ae2d27b5da9..22edea6ca4b8 100644 --- a/drivers/net/wan/fsl_ucc_hdlc.c +++ b/drivers/net/wan/fsl_ucc_hdlc.c @@ -1231,7 +1231,7 @@ static int ucc_hdlc_probe(struct platform_device *pdev) dev->watchdog_timeo = 2 * HZ; hdlc->attach = ucc_hdlc_attach; hdlc->xmit = ucc_hdlc_tx; - netif_napi_add(dev, _priv->napi, ucc_hdlc_poll, 32); + netif_napi_add_weight(dev, _priv->napi, ucc_hdlc_poll, 32); if (register_hdlc_device(dev)) { ret = -ENOBUFS; pr_err("ucc_hdlc: unable to register hdlc device\n"); diff --git a/drivers/net/wan/hd64572.c b/drivers/net/wan/hd64572.c index b89b03a6aba7..534369ffe5de 100644 --- a/drivers/net/wan/hd64572.c +++ b/drivers/net/wan/hd64572.c @@ -173,7 +173,8 @@ static void sca_init_port(port_t *port) sca_out(DIR_EOME, DIR_TX(port->chan), card); /* enable interrupts */ sca_set_carrier(port); - netif_napi_add(port->netdev, >napi, sca_poll, NAPI_WEIGHT); + netif_napi_add_weight(port->netdev, >napi, sca_poll, + NAPI_WEIGHT); } /* MSCI interrupt service */ diff --git a/drivers/net/wan/ixp4xx_hss.c b/drivers/net/wan/ixp4xx_hss.c index 863c3e34e136..e46b7f5ee49e 100644 --- a/drivers/net/wan/ixp4xx_hss.c +++ b/drivers/net/wan/ixp4xx_hss.c @@ -1504,7 +1504,7 @@ static int ixp4xx_hss_probe(struct platform_device *pdev) port->clock_reg = CLK42X_SPEED_2048KHZ; port->id = pdev->id; port->dev = >dev; - netif_napi_add(ndev, >napi, hss_hdlc_poll, NAPI_WEIGHT); + netif_napi_add_weight(ndev, >napi, hss_hdlc_poll, NAPI_WEIGHT); err = register_hdlc_device(ndev); if (err) diff --git a/drivers/net/wan/lapbether.c b/drivers/net/wan/lapbether.c index 282192b82404..960f1393595c 100644 --- a/drivers/net/wan/lapbether.c +++ b/drivers/net/wan/lapbether.c @@ -408,7 +408,7 @@ static int lapbeth_new_device(struct net_device *dev) spin_lock_init(>up_lock); skb_queue_head_init(>rx_queue); - netif_napi_add(ndev, >napi, lapbeth_napi_poll, 16); + netif_napi_add_weight(ndev, >napi, lapbeth_napi_poll, 16); rc = -EIO; if (register_netdevice(ndev)) -- 2.34.1
[PATCH] powerpc/crash: save cpu register data in crash_smp_send_stop()
Capture register data for secondary CPUs in crash_smp_send_stop() instead of doing it much later in crash_kexec_prepare_cpus() function with another set of NMI IPIs to secondary CPUs. This change avoids unnecessarily tricky post processing of data to get the right backtrace for these CPUs. Signed-off-by: Hari Bathini --- arch/powerpc/kernel/smp.c | 40 -- arch/powerpc/kexec/crash.c | 58 ++ 2 files changed, 40 insertions(+), 58 deletions(-) diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index de0f6f09a5dd..7621c3d84c1c 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -60,7 +60,6 @@ #include #include #include -#include #ifdef DEBUG #include @@ -620,45 +619,6 @@ void crash_send_ipi(void (*crash_ipi_callback)(struct pt_regs *)) } #endif -#ifdef CONFIG_NMI_IPI -static void crash_stop_this_cpu(struct pt_regs *regs) -#else -static void crash_stop_this_cpu(void *dummy) -#endif -{ - /* -* Just busy wait here and avoid marking CPU as offline to ensure -* register data is captured appropriately. -*/ - while (1) - cpu_relax(); -} - -void crash_smp_send_stop(void) -{ - static bool stopped = false; - - /* -* In case of fadump, register data for all CPUs is captured by f/w -* on ibm,os-term rtas call. Skip IPI callbacks to other CPUs before -* this rtas call to avoid tricky post processing of those CPUs' -* backtraces. -*/ - if (should_fadump_crash()) - return; - - if (stopped) - return; - - stopped = true; - -#ifdef CONFIG_NMI_IPI - smp_send_nmi_ipi(NMI_IPI_ALL_OTHERS, crash_stop_this_cpu, 100); -#else - smp_call_function(crash_stop_this_cpu, NULL, 0); -#endif /* CONFIG_NMI_IPI */ -} - #ifdef CONFIG_NMI_IPI static void nmi_stop_this_cpu(struct pt_regs *regs) { diff --git a/arch/powerpc/kexec/crash.c b/arch/powerpc/kexec/crash.c index 22ceeeb705ab..f06dfe71caca 100644 --- a/arch/powerpc/kexec/crash.c +++ b/arch/powerpc/kexec/crash.c @@ -25,6 +25,7 @@ #include #include #include +#include /* * The primary CPU waits a while for all secondary CPUs to enter. This is to @@ -102,7 +103,7 @@ void crash_ipi_callback(struct pt_regs *regs) /* NOTREACHED */ } -static void crash_kexec_prepare_cpus(int cpu) +static void crash_kexec_prepare_cpus(void) { unsigned int msecs; volatile unsigned int ncpus = num_online_cpus() - 1;/* Excluding the panic cpu */ @@ -203,7 +204,7 @@ void crash_kexec_secondary(struct pt_regs *regs) #else /* ! CONFIG_SMP */ -static void crash_kexec_prepare_cpus(int cpu) +static void crash_kexec_prepare_cpus(void) { /* * move the secondaries to us so that we can copy @@ -249,6 +250,42 @@ static void __maybe_unused crash_kexec_wait_realmode(int cpu) static inline void crash_kexec_wait_realmode(int cpu) {} #endif /* CONFIG_SMP && CONFIG_PPC64 */ +void crash_smp_send_stop(void) +{ + static int cpus_stopped; + + /* +* In case of fadump, register data for all CPUs is captured by f/w +* on ibm,os-term rtas call. Skip IPI callbacks to other CPUs before +* this rtas call to avoid tricky post processing of those CPUs' +* backtraces. +*/ + if (should_fadump_crash()) + return; + + if (cpus_stopped) + return; + + cpus_stopped = 1; + + /* Avoid hardlocking with irresponsive CPU holding logbuf_lock */ + printk_deferred_enter(); + + /* +* This function is only called after the system +* has panicked or is otherwise in a critical state. +* The minimum amount of code to allow a kexec'd kernel +* to run successfully needs to happen here. +* +* In practice this means stopping other cpus in +* an SMP system. +* The kernel is broken so disable interrupts. +*/ + hard_irq_disable(); + + crash_kexec_prepare_cpus(); +} + /* * Register a function to be called on shutdown. Only use this if you * can't reset your device in the second kernel. @@ -312,21 +349,6 @@ void default_machine_crash_shutdown(struct pt_regs *regs) unsigned int i; int (*old_handler)(struct pt_regs *regs); - /* Avoid hardlocking with irresponsive CPU holding logbuf_lock */ - printk_deferred_enter(); - - /* -* This function is only called after the system -* has panicked or is otherwise in a critical state. -* The minimum amount of code to allow a kexec'd kernel -* to run successfully needs to happen here. -* -* In practice this means stopping other cpus in -* an SMP system. -* The kernel is broken so disable interrupts. -*/ - hard_irq_disable(); - /* * Make a note of crashing cpu.
Re: [PATCH] crypto: vmx - Align the short log with Makefile cleanups
Hi Herbert, On Fri, May 6, 2022 at 7:23 PM Herbert Xu wrote: > > On Sun, May 01, 2022 at 10:07:49PM +0900, Masahiro Yamada wrote: > > I notieced the log is not properly aligned: > > > > PERL drivers/crypto/vmx/aesp8-ppc.S > > CC [M] fs/xfs/xfs_reflink.o > > PERL drivers/crypto/vmx/ghashp8-ppc.S > > CC [M] drivers/crypto/vmx/aes.o > > > > Add some spaces after 'PERL'. > > > > While I was here, I cleaned up the Makefile: > > > > - Merge the two similar rules > > > > - Remove redundant 'clean-files' (Having 'targets' is enough) > > > > - Move the flavour into the build command > > > > This still avoids the build failures fixed by commit 4ee812f6143d > > ("crypto: vmx - Avoid weird build failures"). > > > > Signed-off-by: Masahiro Yamada > > --- > > > > drivers/crypto/vmx/Makefile | 17 +++-- > > 1 file changed, 3 insertions(+), 14 deletions(-) > > Patch applied. Thanks. Sorry, I just noticed the 0day bot had reported the error. I sent v2.(CONFIG_LITTLE_ENDIAN --> CONFIG_CPU_LITTLE_ENDIAN) https://lore.kernel.org/lkml/20220506150820.1310802-1-masahi...@kernel.org/ Could you replace it, or fix it up, please? -- Best Regards Masahiro Yamada
[PATCH v2] crypto: vmx - Align the short log with Makefile cleanups
I notieced the log is not properly aligned: PERL drivers/crypto/vmx/aesp8-ppc.S CC [M] fs/xfs/xfs_reflink.o PERL drivers/crypto/vmx/ghashp8-ppc.S CC [M] drivers/crypto/vmx/aes.o Add some spaces after 'PERL'. While I was here, I cleaned up the Makefile: - Merge the two similar rules - Remove redundant 'clean-files' (Having 'targets' is enough) - Move the flavour into the build command This still avoids the build failures fixed by commit 4ee812f6143d ("crypto: vmx - Avoid weird build failures"). Signed-off-by: Masahiro Yamada --- Changes in v2: - Fix CONFIG_LITTLE_ENDIAN -> CONFIG_CPU_LITTLE_ENDIAN drivers/crypto/vmx/Makefile | 17 +++-- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/drivers/crypto/vmx/Makefile b/drivers/crypto/vmx/Makefile index 709670d2b553..2560cfea1dec 100644 --- a/drivers/crypto/vmx/Makefile +++ b/drivers/crypto/vmx/Makefile @@ -2,21 +2,10 @@ obj-$(CONFIG_CRYPTO_DEV_VMX_ENCRYPT) += vmx-crypto.o vmx-crypto-objs := vmx.o aesp8-ppc.o ghashp8-ppc.o aes.o aes_cbc.o aes_ctr.o aes_xts.o ghash.o -ifeq ($(CONFIG_CPU_LITTLE_ENDIAN),y) -override flavour := linux-ppc64le -else -override flavour := linux-ppc64 -endif - -quiet_cmd_perl = PERL $@ - cmd_perl = $(PERL) $(<) $(flavour) > $(@) +quiet_cmd_perl = PERL$@ + cmd_perl = $(PERL) $< $(if $(CONFIG_CPU_LITTLE_ENDIAN), linux-ppc64le, linux-ppc64) > $@ targets += aesp8-ppc.S ghashp8-ppc.S -$(obj)/aesp8-ppc.S: $(src)/aesp8-ppc.pl FORCE - $(call if_changed,perl) - -$(obj)/ghashp8-ppc.S: $(src)/ghashp8-ppc.pl FORCE +$(obj)/aesp8-ppc.S $(obj)/ghashp8-ppc.S: $(obj)/%.S: $(src)/%.pl FORCE $(call if_changed,perl) - -clean-files := aesp8-ppc.S ghashp8-ppc.S -- 2.32.0
Re: [RFC v2 01/39] Kconfig: introduce HAS_IOPORT option and select it as necessary
Hi Geert, > > Sane access would require a single CPU instruction to read or write from > > the configuration space. To access the conventional PCI configuration > > space in a direct linear manner you need 256 * 21 * 8 * 256 = 10.5MiB of > > address space. Such amount of address space seems affordable even with > > 32-bit systems. > > Won't have fit in the legacy 1 MiB space ("640 KiB..."). Haha, but anyway you're supposed to use BIOS calls under DOS and the like so it doesn't really matter. You can't poke at the APIC in the legacy space either. Maciej
Re: [RFC v2 01/39] Kconfig: introduce HAS_IOPORT option and select it as necessary
Hi David On Fri, May 6, 2022 at 4:05 PM David Laight wrote: > From: Geert Uytterhoeven > > Sent: 06 May 2022 14:09 > > > The same is really true for other bus type - including ISA and EISA. > > > (Ignoring the horrid of probing ISI bus devices - hopefully they > > > are in the ACPI tables??_ > > > If a driver is probed on a ISA bus there ought to be functions > > > equivalent to pci_ioremap() (for both memory and IO addresses) > > > that return tokens appropriate for the specific bus. > > > > > > That is all a different load of churn. > > > > A lng time ago, it was suggested to add register accessor > > functions to struct device, so e.g. readl(dev, offset) would call > > into these accessors, which would implement the bus-specific behavior. > > No more worries about readl(), __raw_readl(), ioread32b(), or whatever > > quirk is needed, at the (small on nowadays' machines) expense of > > some indirection... > > I was just thinking that the access functions might need a 'device'. > Although you also need the BAR (or equivalent). > So readl(dev, bar_token, offset) or readl(dev, bar_token + offset). Note that we do have such a system: regmap. > Clearly the 'dev' parameter could be compiled out for non-DEBUG > build on x86 - leaving the current(ish) object code. Assumed all devices are PCI devices. E.g. USB devices would still need the indirection. > You don't want an indirect call (this year), but maybe real > function call and a few tests won't make that much difference. > They might affect PCIe writes, but PCIe reads are so slow you > need to avoid them whenever possible. > I've not timed reads into something like an ethernet chip, > but into our fpga they are probably 1000 clocks+. > > OTOH I wouldn't want any overhead on the PIO fifo reads > on one of our small ppc devices. > We push a lot of data though that fifo and anything extra > would kill performance. Right. Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
Re: [RFC v2 01/39] Kconfig: introduce HAS_IOPORT option and select it as necessary
Hi Maciej, On Fri, May 6, 2022 at 4:44 PM Maciej W. Rozycki wrote: > On Fri, 6 May 2022, David Laight wrote: > > > It was retrofitted in that x86 systems already existed for ~15 years when > > > PCI came into picture. Therefore the makers of the CPU ISA couldn't have > > > envisaged the need for config access instructions like they did for memory > > > and port access. > > > > Rev 2.0 of the PCI spec (1993) defines two mechanisms for config cycles. > > #2 is probably the first one and maps all of PCI config space into > > 4k of IO space (PCI bridges aren't supported). > > This one is even more horrid than #1 in that it requires two separate > preparatory I/O writes rather than just one, one to the Forward Register > (at 0xcfa) to set the bus number, and another to the Configuration Space > Enable Register (at 0xcf8) to set the function number, before you can > issue a configuration read or write to a device. So you need MP locking > too. > > NB only peer bridges aren't supported with this mechanism, normal PCI-PCI > bridges are, via the Forward Register. > > > #1 requires a pair of accesses (and SMP locking). > > > > Neither is really horrid. > > Both are. First neither is MP-safe and second both are indirect in that > you need to poke at some chipset registers before you can issue the actual > read or write. > > Sane access would require a single CPU instruction to read or write from > the configuration space. To access the conventional PCI configuration > space in a direct linear manner you need 256 * 21 * 8 * 256 = 10.5MiB of > address space. Such amount of address space seems affordable even with > 32-bit systems. Won't have fit in the legacy 1 MiB space ("640 KiB..."). Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
RE: [RFC v2 01/39] Kconfig: introduce HAS_IOPORT option and select it as necessary
On Fri, 6 May 2022, David Laight wrote: > > It was retrofitted in that x86 systems already existed for ~15 years when > > PCI came into picture. Therefore the makers of the CPU ISA couldn't have > > envisaged the need for config access instructions like they did for memory > > and port access. > > Rev 2.0 of the PCI spec (1993) defines two mechanisms for config cycles. > #2 is probably the first one and maps all of PCI config space into > 4k of IO space (PCI bridges aren't supported). This one is even more horrid than #1 in that it requires two separate preparatory I/O writes rather than just one, one to the Forward Register (at 0xcfa) to set the bus number, and another to the Configuration Space Enable Register (at 0xcf8) to set the function number, before you can issue a configuration read or write to a device. So you need MP locking too. NB only peer bridges aren't supported with this mechanism, normal PCI-PCI bridges are, via the Forward Register. > #1 requires a pair of accesses (and SMP locking). > > Neither is really horrid. Both are. First neither is MP-safe and second both are indirect in that you need to poke at some chipset registers before you can issue the actual read or write. Sane access would require a single CPU instruction to read or write from the configuration space. To access the conventional PCI configuration space in a direct linear manner you need 256 * 21 * 8 * 256 = 10.5MiB of address space. Such amount of address space seems affordable even with 32-bit systems. Maciej
Re: [PATCH kernel] KVM: PPC: Book3s: PR: Enable default TCE hypercalls
Alexey Kardashevskiy writes: > When KVM_CAP_PPC_ENABLE_HCALL was introduced, H_GET_TCE and H_PUT_TCE > were already implemented and enabled by default; however H_GET_TCE > was missed out on PR KVM (probably because the handler was in > the real mode code at the time). > > This enables H_GET_TCE by default. While at this, this wraps > the checks in ifdef CONFIG_SPAPR_TCE_IOMMU just like HV KVM. > > Signed-off-by: Alexey Kardashevskiy Reviewed-by: Fabiano Rosas
RE: [RFC v2 01/39] Kconfig: introduce HAS_IOPORT option and select it as necessary
From: Geert Uytterhoeven > Sent: 06 May 2022 14:09 ... > > The same is really true for other bus type - including ISA and EISA. > > (Ignoring the horrid of probing ISI bus devices - hopefully they > > are in the ACPI tables??_ > > If a driver is probed on a ISA bus there ought to be functions > > equivalent to pci_ioremap() (for both memory and IO addresses) > > that return tokens appropriate for the specific bus. > > > > That is all a different load of churn. > > A lng time ago, it was suggested to add register accessor > functions to struct device, so e.g. readl(dev, offset) would call > into these accessors, which would implement the bus-specific behavior. > No more worries about readl(), __raw_readl(), ioread32b(), or whatever > quirk is needed, at the (small on nowadays' machines) expense of > some indirection... I was just thinking that the access functions might need a 'device'. Although you also need the BAR (or equivalent). So readl(dev, bar_token, offset) or readl(dev, bar_token + offset). Clearly the 'dev' parameter could be compiled out for non-DEBUG build on x86 - leaving the current(ish) object code. You don't want an indirect call (this year), but maybe real function call and a few tests won't make that much difference. They might affect PCIe writes, but PCIe reads are so slow you need to avoid them whenever possible. I've not timed reads into something like an ethernet chip, but into our fpga they are probably 1000 clocks+. OTOH I wouldn't want any overhead on the PIO fifo reads on one of our small ppc devices. We push a lot of data though that fifo and anything extra would kill performance. David - Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK Registration No: 1397386 (Wales)
Re: [RFC v2 01/39] Kconfig: introduce HAS_IOPORT option and select it as necessary
On Fri, 6 May 2022, Geert Uytterhoeven wrote: > A lng time ago, it was suggested to add register accessor > functions to struct device, so e.g. readl(dev, offset) would call > into these accessors, which would implement the bus-specific behavior. > No more worries about readl(), __raw_readl(), ioread32b(), or whatever > quirk is needed, at the (small on nowadays' machines) expense of > some indirection... I guess you'd need an additional parameter for the endianness policy required (to match either bit or byte lanes, according to ultimate data interpretation) where crossing between buses of a different endianness each. Otherwise you'd end up with the mess elsewhere. Maciej
RE: [RFC v2 01/39] Kconfig: introduce HAS_IOPORT option and select it as necessary
From: Maciej W. Rozycki > Sent: 06 May 2022 14:15 > On Fri, 6 May 2022, David Laight wrote: > > > > The PCI configuration space was retrofitted into x86 systems (and is > > > accessed in an awkward manner with them), but with a new design such a > > > clean approach is most welcome IMHO. Thank you for your explanation. > > > > Actually I think x86 was the initial system for PCI. > > The PCI config space 'mess' is all about trying to make > > something that wouldn't break existing memory maps. > > It was retrofitted in that x86 systems already existed for ~15 years when > PCI came into picture. Therefore the makers of the CPU ISA couldn't have > envisaged the need for config access instructions like they did for memory > and port access. Rev 2.0 of the PCI spec (1993) defines two mechanisms for config cycles. #2 is probably the first one and maps all of PCI config space into 4k of IO space (PCI bridges aren't supported). #1 requires a pair of accesses (and SMP locking). Neither is really horrid. For horrid try the ISApnp interface. David - Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK Registration No: 1397386 (Wales)
Re: [PATCH] powerpc/perf: Add support for caps under sysfs in powerpc
Hi Athira, Some comments below :) Athira Rajeev writes: > Add caps support under "/sys/bus/event_source/devices//" > for powerpc. This directory can be used to expose some of the > specific features that powerpc PMU supports to the user. > Example: pmu_name. The name of PMU registered will depend on > platform, say power9 or power10 or it could be Generic Compat > PMU. Is there precedent for adding a "caps" directory? ie. do other PMUs on other architectures already do that? Is there precedent for adding "pmu_name"? I don't see any mention of them in Documentation/ABI anywhere. If we're the first to do that we should add it to the documentation. As this would set a precedent for other PMUs, please Cc the perf maintainers on v2. > Currently the only way to know which is the registered > PMU is from the dmesg logs. But clearing the dmesg will make it > difficult to know exact PMU backend used. And even extracting > from dmesg will be complicated, as we need to parse the dmesg > logs and add filters for pmu name. Whereas by exposing it via > caps will make it easy as we just need to directly read it from > the sysfs. > > Add a caps directory to /sys/bus/event_source/devices/cpu/ > for power8, power9, power10 and generic compat PMU. > > The information exposed currently: > - pmu_name : Underlying PMU name from the driver > > Example result with power9 pmu: > > # ls /sys/bus/event_source/devices/cpu/caps > pmu_name > > # cat /sys/bus/event_source/devices/cpu/caps/pmu_name > power9 > > Signed-off-by: Athira Rajeev > Reviewed-by: Madhavan Srinivasan > --- > arch/powerpc/perf/generic-compat-pmu.c | 20 > arch/powerpc/perf/power10-pmu.c| 20 > arch/powerpc/perf/power8-pmu.c | 20 > arch/powerpc/perf/power9-pmu.c | 20 > 4 files changed, 80 insertions(+) > > diff --git a/arch/powerpc/perf/generic-compat-pmu.c > b/arch/powerpc/perf/generic-compat-pmu.c > index f3db88aee4dd..7b5fe2d89007 100644 > --- a/arch/powerpc/perf/generic-compat-pmu.c > +++ b/arch/powerpc/perf/generic-compat-pmu.c > @@ -151,9 +151,29 @@ static const struct attribute_group > generic_compat_pmu_format_group = { > .attrs = generic_compat_pmu_format_attr, > }; > > +static ssize_t pmu_name_show(struct device *cdev, > + struct device_attribute *attr, > + char *buf) > +{ > + return snprintf(buf, PAGE_SIZE, "generic_compat_pmu"); > +} That's not a great name, now that it's exposed to userspace. For starters it's only generic on Book3S, and if you look at init_generic_compat_pmu() it's really a "ISA >= v3.0 fallback PMU" - or something like that. > +static DEVICE_ATTR_RO(pmu_name); > + > +static struct attribute *generic_compat_pmu_caps_attrs[] = { > + _attr_pmu_name.attr, > + NULL > +}; > + > +static struct attribute_group generic_compat_pmu_caps_group = { > + .name = "caps", > + .attrs = generic_compat_pmu_caps_attrs, > +}; > + > static const struct attribute_group *generic_compat_pmu_attr_groups[] = { > _compat_pmu_format_group, > _compat_pmu_events_group, > + _compat_pmu_caps_group, > NULL, > }; > > diff --git a/arch/powerpc/perf/power10-pmu.c b/arch/powerpc/perf/power10-pmu.c > index d3398100a60f..a622ff783719 100644 > --- a/arch/powerpc/perf/power10-pmu.c > +++ b/arch/powerpc/perf/power10-pmu.c > @@ -258,6 +258,25 @@ static const struct attribute_group > power10_pmu_format_group = { > .attrs = power10_pmu_format_attr, > }; > > +static ssize_t pmu_name_show(struct device *cdev, > + struct device_attribute *attr, > + char *buf) > +{ > + return snprintf(buf, PAGE_SIZE, "power10"); I believe that should use sysfs_emit(). > +} > + > +static DEVICE_ATTR_RO(pmu_name); > + > +static struct attribute *power10_pmu_caps_attrs[] = { > + _attr_pmu_name.attr, > + NULL > +}; > + > +static struct attribute_group power10_pmu_caps_group = { > + .name = "caps", > + .attrs = power10_pmu_caps_attrs, > +}; > + > static const struct attribute_group *power10_pmu_attr_groups_dd1[] = { > _pmu_format_group, > _pmu_events_group_dd1, > @@ -267,6 +286,7 @@ static const struct attribute_group > *power10_pmu_attr_groups_dd1[] = { > static const struct attribute_group *power10_pmu_attr_groups[] = { > _pmu_format_group, > _pmu_events_group, > + _pmu_caps_group, > NULL, > }; There's a lot of boiler plate repeated for each PMU. We already have power_pmu->name, can we use that and make the show function generic at least in core-book3s.c ? cheers
Re: [RFC v2 01/39] Kconfig: introduce HAS_IOPORT option and select it as necessary
On Fri, 6 May 2022, Arnd Bergmann wrote: > > So what happens if the instruction is given an I/O rather than memory BAR > > as the relevant argument? Is the address space indicator bit (bit #0) > > simply ignored or what? > > Not sure. My best guess is that it would actually work as you'd expect, > but is deliberately left out of the architecture specification so they don't > have to to validate the correctness. Note that only a small number of > PCIe cards are actually supported by IBM, and I think the firmware > only passes devices to the OS if they are whitelisted. That makes sense, thanks! Maciej
Re: [RFC v2 01/39] Kconfig: introduce HAS_IOPORT option and select it as necessary
On Fri, 2022-05-06 at 14:53 +0200, Arnd Bergmann wrote: > On Fri, May 6, 2022 at 2:27 PM Maciej W. Rozycki wrote: > > On Fri, 6 May 2022, Arnd Bergmann wrote: > > > > > > If this is PCI/PCIe indeed, then an I/O access is just a different bit > > > > pattern put on the bus/in the TLP in the address phase. So what is > > > > there > > > > inherent to the s390 architecture that prevents that different bit > > > > pattern > > > > from being used? > > > > > > The hardware design for PCI on s390 is very different from any other > > > architecture, and more abstract. Rather than implementing MMIO register > > > access as pointer dereference, this is a separate CPU instruction that > > > takes a device/bar plus offset as arguments rather than a pointer, and > > > Linux encodes this back into a fake __iomem token. > > > > OK, that seems to me like a reasonable and quite a clean design (on the > > hardware side). > > > > So what happens if the instruction is given an I/O rather than memory BAR > > as the relevant argument? Is the address space indicator bit (bit #0) > > simply ignored or what? > > Not sure. My best guess is that it would actually work as you'd expect, > but is deliberately left out of the architecture specification so they don't > have to to validate the correctness. Note that only a small number of > PCIe cards are actually supported by IBM, and I think the firmware > only passes devices to the OS if they are whitelisted. > > Arnd Yes, though in Linux we do try hard to work with whatever is plugged in. We did benefit from this in the past working with a new NIC from a different vendor with 0 additional changes. Also you can use vfio-pci to pass-through arbitrary PCI devices to a QEMU emulating s390x.
RE: [RFC v2 01/39] Kconfig: introduce HAS_IOPORT option and select it as necessary
On Fri, 6 May 2022, David Laight wrote: > > The PCI configuration space was retrofitted into x86 systems (and is > > accessed in an awkward manner with them), but with a new design such a > > clean approach is most welcome IMHO. Thank you for your explanation. > > Actually I think x86 was the initial system for PCI. > The PCI config space 'mess' is all about trying to make > something that wouldn't break existing memory maps. It was retrofitted in that x86 systems already existed for ~15 years when PCI came into picture. Therefore the makers of the CPU ISA couldn't have envisaged the need for config access instructions like they did for memory and port access. Maciej
Re: [RFC v2 01/39] Kconfig: introduce HAS_IOPORT option and select it as necessary
On Fri, May 6, 2022 at 2:56 PM David Laight wrote: > From: Maciej W. Rozycki > > Sent: 06 May 2022 13:27 > > On Fri, 6 May 2022, Arnd Bergmann wrote: > > > > If this is PCI/PCIe indeed, then an I/O access is just a different bit > > > > pattern put on the bus/in the TLP in the address phase. So what is > > > > there > > > > inherent to the s390 architecture that prevents that different bit > > > > pattern > > > > from being used? > > > > > > The hardware design for PCI on s390 is very different from any other > > > architecture, and more abstract. Rather than implementing MMIO register > > > access as pointer dereference, this is a separate CPU instruction that > > > takes a device/bar plus offset as arguments rather than a pointer, and > > > Linux encodes this back into a fake __iomem token. > > > > OK, that seems to me like a reasonable and quite a clean design (on the > > hardware side). > > > > So what happens if the instruction is given an I/O rather than memory BAR > > as the relevant argument? Is the address space indicator bit (bit #0) > > simply ignored or what? > > You don't understand something... > > For a memory BAR pci_ioremap() returns a token that can be used with readl(). > On most architectures readl() is just a memory access. > This all fails on an I/O BAR. > > For an I/O BAR you want a similar pair of functions. > On x86 the access function would need to use the 'in/out' instructions but > there is no requirement for the token to be the native io port number. > On many non-x86 architectures the access function would be a simple memory > access - but a specific system (eg many ppc) may never actually allow > such mappings to succeed. > > You might also want a third PCI mapping function that can map a memory > BAR or an I/O BAR - with a suitable access function. > On x86 this would need something like ioread8() for accesses. > Except that function uses small integers for io port numbers > (which is inherently dangerous). > > Nothing except the architecture specific implementation of the function > to access an io BAR would ever go near a function called inb(). > > The same is really true for other bus type - including ISA and EISA. > (Ignoring the horrid of probing ISI bus devices - hopefully they > are in the ACPI tables??_ > If a driver is probed on a ISA bus there ought to be functions > equivalent to pci_ioremap() (for both memory and IO addresses) > that return tokens appropriate for the specific bus. > > That is all a different load of churn. A lng time ago, it was suggested to add register accessor functions to struct device, so e.g. readl(dev, offset) would call into these accessors, which would implement the bus-specific behavior. No more worries about readl(), __raw_readl(), ioread32b(), or whatever quirk is needed, at the (small on nowadays' machines) expense of some indirection... Gr{oetje,eeting}s, Geert -- Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- ge...@linux-m68k.org In personal conversations with technical people, I call myself a hacker. But when I'm talking to journalists I just say "programmer" or something like that. -- Linus Torvalds
Re: [RFC v2 01/39] Kconfig: introduce HAS_IOPORT option and select it as necessary
On Fri, 2022-05-06 at 13:27 +0100, Maciej W. Rozycki wrote: > On Fri, 6 May 2022, Arnd Bergmann wrote: > > > > If this is PCI/PCIe indeed, then an I/O access is just a different bit > > > pattern put on the bus/in the TLP in the address phase. So what is there > > > inherent to the s390 architecture that prevents that different bit pattern > > > from being used? > > > > The hardware design for PCI on s390 is very different from any other > > architecture, and more abstract. Rather than implementing MMIO register > > access as pointer dereference, this is a separate CPU instruction that > > takes a device/bar plus offset as arguments rather than a pointer, and > > Linux encodes this back into a fake __iomem token. > > OK, that seems to me like a reasonable and quite a clean design (on the > hardware side). > > So what happens if the instruction is given an I/O rather than memory BAR > as the relevant argument? Is the address space indicator bit (bit #0) > simply ignored or what? See my answer to Arnd for some more background but there simply isn't a way to formulate an I/O access. In the old style PCI instructions the BAR number and the function handle are put in a register before the access. BAR number 15 is used to access config space. If there is no BAR for that number the instruction fails with a non-zero CC. > > > > But that has nothing to do with the presence or absence of any specific > > > processor instructions. It's just a limitation of bus glue. So I guess > > > it's just that all PCI/PCIe glue logic implementations for s390 have such > > > a limitation, right? > > > > There are separate instructions for PCI memory and config space, but > > no instructions for I/O space, or for non-PCI MMIO that it could be mapped > > into. > > The PCI configuration space was retrofitted into x86 systems (and is > accessed in an awkward manner with them), but with a new design such a > clean approach is most welcome IMHO. Thank you for your explanation. > > Maciej Well our design is a retrofit too considering s390x is a direct decendent of IBM System/360 which one could argue to have been the first ISA. But yes as PCI support was only added with PCIe and with a machine level hypervisor already in place we do get shielded a lot from the gritty details.
RE: [RFC v2 01/39] Kconfig: introduce HAS_IOPORT option and select it as necessary
From: Maciej W. Rozycki > Sent: 06 May 2022 13:27 > > On Fri, 6 May 2022, Arnd Bergmann wrote: > > > > If this is PCI/PCIe indeed, then an I/O access is just a different bit > > > pattern put on the bus/in the TLP in the address phase. So what is there > > > inherent to the s390 architecture that prevents that different bit pattern > > > from being used? > > > > The hardware design for PCI on s390 is very different from any other > > architecture, and more abstract. Rather than implementing MMIO register > > access as pointer dereference, this is a separate CPU instruction that > > takes a device/bar plus offset as arguments rather than a pointer, and > > Linux encodes this back into a fake __iomem token. > > OK, that seems to me like a reasonable and quite a clean design (on the > hardware side). > > So what happens if the instruction is given an I/O rather than memory BAR > as the relevant argument? Is the address space indicator bit (bit #0) > simply ignored or what? You don't understand something... For a memory BAR pci_ioremap() returns a token that can be used with readl(). On most architectures readl() is just a memory access. This all fails on an I/O BAR. For an I/O BAR you want a similar pair of functions. On x86 the access function would need to use the 'in/out' instructions but there is no requirement for the token to be the native io port number. On many non-x86 architectures the access function would be a simple memory access - but a specific system (eg many ppc) may never actually allow such mappings to succeed. You might also want a third PCI mapping function that can map a memory BAR or an I/O BAR - with a suitable access function. On x86 this would need something like ioread8() for accesses. Except that function uses small integers for io port numbers (which is inherently dangerous). Nothing except the architecture specific implementation of the function to access an io BAR would ever go near a function called inb(). The same is really true for other bus type - including ISA and EISA. (Ignoring the horrid of probing ISI bus devices - hopefully they are in the ACPI tables??_ If a driver is probed on a ISA bus there ought to be functions equivalent to pci_ioremap() (for both memory and IO addresses) that return tokens appropriate for the specific bus. That is all a different load of churn. > > > But that has nothing to do with the presence or absence of any specific > > > processor instructions. It's just a limitation of bus glue. So I guess > > > it's just that all PCI/PCIe glue logic implementations for s390 have such > > > a limitation, right? > > > > There are separate instructions for PCI memory and config space, but > > no instructions for I/O space, or for non-PCI MMIO that it could be mapped > > into. > > The PCI configuration space was retrofitted into x86 systems (and is > accessed in an awkward manner with them), but with a new design such a > clean approach is most welcome IMHO. Thank you for your explanation. Actually I think x86 was the initial system for PCI. The PCI config space 'mess' is all about trying to make something that wouldn't break existing memory maps. David - Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK Registration No: 1397386 (Wales)
Re: [RFC v2 01/39] Kconfig: introduce HAS_IOPORT option and select it as necessary
On Fri, May 6, 2022 at 2:27 PM Maciej W. Rozycki wrote: > > On Fri, 6 May 2022, Arnd Bergmann wrote: > > > > If this is PCI/PCIe indeed, then an I/O access is just a different bit > > > pattern put on the bus/in the TLP in the address phase. So what is there > > > inherent to the s390 architecture that prevents that different bit pattern > > > from being used? > > > > The hardware design for PCI on s390 is very different from any other > > architecture, and more abstract. Rather than implementing MMIO register > > access as pointer dereference, this is a separate CPU instruction that > > takes a device/bar plus offset as arguments rather than a pointer, and > > Linux encodes this back into a fake __iomem token. > > OK, that seems to me like a reasonable and quite a clean design (on the > hardware side). > > So what happens if the instruction is given an I/O rather than memory BAR > as the relevant argument? Is the address space indicator bit (bit #0) > simply ignored or what? Not sure. My best guess is that it would actually work as you'd expect, but is deliberately left out of the architecture specification so they don't have to to validate the correctness. Note that only a small number of PCIe cards are actually supported by IBM, and I think the firmware only passes devices to the OS if they are whitelisted. Arnd
Re: [RFC v2 01/39] Kconfig: introduce HAS_IOPORT option and select it as necessary
On Fri, 2022-05-06 at 13:33 +0200, Arnd Bergmann wrote: > On Fri, May 6, 2022 at 12:20 PM Maciej W. Rozycki wrote: > > On Thu, 5 May 2022, Arnd Bergmann wrote: > > I think I'm missing something here. IIUC we're talking about a PCI/PCIe > > bus used with s390 hardware, right? > > > > (It has to be PCI/PCIe, because other than x86/IA-64 host buses there are > > only PCI/PCIe and EISA/ISA buses out there that define I/O access cycles > > and EISA/ISA have long been obsoleted except perhaps from some niche use.) > > > > If this is PCI/PCIe indeed, then an I/O access is just a different bit > > pattern put on the bus/in the TLP in the address phase. So what is there > > inherent to the s390 architecture that prevents that different bit pattern > > from being used? > > The hardware design for PCI on s390 is very different from any other > architecture, and more abstract. Rather than implementing MMIO register > access as pointer dereference, this is a separate CPU instruction that > takes a device/bar plus offset as arguments rather than a pointer, and > Linux encodes this back into a fake __iomem token. Correct, we have since gained new PCI load/store instructions that actually do take a virtual address that gets address translated to a "physical address" for the PCI BARs. The "physical address" we get from the platform (again via special instructions). I put "physical address" in quotes because while they are conceptually physical addresses and they are translated to by MMU translation tables, accessing their virtual mapping with any instruction other then the special PCI load/store instructions will cause addressing exceptions. So we still don't have real MMIO but something that looks a lot more like MMIO than we used to. > > > If anything, I could imagine the same limitation as with current POWER9 > > implementations, that is whatever glue is used to wire PCI/PCIe to the > > rest of the system does not implement a way to use said bit pattern (which > > has nothing to do with the POWER9 processor instruction set). > > > > But that has nothing to do with the presence or absence of any specific > > processor instructions. It's just a limitation of bus glue. So I guess > > it's just that all PCI/PCIe glue logic implementations for s390 have such > > a limitation, right? > > There are separate instructions for PCI memory and config space, but > no instructions for I/O space, or for non-PCI MMIO that it could be mapped > into. > >Arnd The config space is still accessed with the old style PCI load/store instructions via a special extra BAR. But yes overall on s390x we can only access PCI(e) devices via special instructions not via real MMIO and also the OS has no direct access to the registers of the PHB which are only accessible to firmware. Maybe as a bit of further background it's also important to note that on s390x all Operating Systems run inside a hypervisor. On the lowest level any OS can run this is a non-paging machine level hypervisor. For PCI that means that we always have a kind of pass-through access though without paging and hardware support for the memory partitioning this is of course relatively simple.
Re: [RFC v2 01/39] Kconfig: introduce HAS_IOPORT option and select it as necessary
On Fri, 6 May 2022, Arnd Bergmann wrote: > > If this is PCI/PCIe indeed, then an I/O access is just a different bit > > pattern put on the bus/in the TLP in the address phase. So what is there > > inherent to the s390 architecture that prevents that different bit pattern > > from being used? > > The hardware design for PCI on s390 is very different from any other > architecture, and more abstract. Rather than implementing MMIO register > access as pointer dereference, this is a separate CPU instruction that > takes a device/bar plus offset as arguments rather than a pointer, and > Linux encodes this back into a fake __iomem token. OK, that seems to me like a reasonable and quite a clean design (on the hardware side). So what happens if the instruction is given an I/O rather than memory BAR as the relevant argument? Is the address space indicator bit (bit #0) simply ignored or what? > > But that has nothing to do with the presence or absence of any specific > > processor instructions. It's just a limitation of bus glue. So I guess > > it's just that all PCI/PCIe glue logic implementations for s390 have such > > a limitation, right? > > There are separate instructions for PCI memory and config space, but > no instructions for I/O space, or for non-PCI MMIO that it could be mapped > into. The PCI configuration space was retrofitted into x86 systems (and is accessed in an awkward manner with them), but with a new design such a clean approach is most welcome IMHO. Thank you for your explanation. Maciej
Re: [PATCH v1 08/22] powerpc/ftrace: Make __ftrace_make_{nop/call}() common to PPC32 and PPC64
Le 18/04/2022 à 08:40, Naveen N. Rao a écrit : > Christophe Leroy wrote: >> Since c93d4f6ecf4b ("powerpc/ftrace: Add module_trampoline_target() >> for PPC32"), __ftrace_make_nop() for PPC32 is very similar to the >> one for PPC64. >> >> Same for __ftrace_make_call(). >> >> Make them common. >> >> Signed-off-by: Christophe Leroy >> --- >> arch/powerpc/kernel/trace/ftrace.c | 108 +++-- >> 1 file changed, 8 insertions(+), 100 deletions(-) >> >> diff --git a/arch/powerpc/kernel/trace/ftrace.c >> b/arch/powerpc/kernel/trace/ftrace.c >> index 1b05d33f96c6..2c7e42e439bb 100644 >> --- a/arch/powerpc/kernel/trace/ftrace.c >> +++ b/arch/powerpc/kernel/trace/ftrace.c >> @@ -114,7 +114,6 @@ static unsigned long find_bl_target(unsigned long >> ip, ppc_inst_t op) >> } >> >> #ifdef CONFIG_MODULES >> -#ifdef CONFIG_PPC64 >> static int >> __ftrace_make_nop(struct module *mod, >> struct dyn_ftrace *rec, unsigned long addr) >> @@ -154,10 +153,11 @@ __ftrace_make_nop(struct module *mod, >> return -EINVAL; >> } >> >> -#ifdef CONFIG_MPROFILE_KERNEL >> - /* When using -mkernel_profile there is no load to jump over */ >> + /* When using -mkernel_profile or PPC32 there is no load to jump >> over */ > -mprofile-kernel > > Since you are modifying that line anyway ^^ > > >> pop = ppc_inst(PPC_RAW_NOP()); >> >> +#ifdef CONFIG_PPC64 >> +#ifdef CONFIG_MPROFILE_KERNEL >> if (copy_inst_from_kernel_nofault(, (void *)(ip - 4))) { >> pr_err("Fetching instruction at %lx failed.\n", ip - 4); >> return -EFAULT; >> @@ -201,6 +201,7 @@ __ftrace_make_nop(struct module *mod, >> return -EINVAL; >> } >> #endif /* CONFIG_MPROFILE_KERNEL */ >> +#endif /* PPC64 */ >> >> if (patch_instruction((u32 *)ip, pop)) { >> pr_err("Patching NOP failed.\n"); >> @@ -209,48 +210,6 @@ __ftrace_make_nop(struct module *mod, >> >> return 0; >> } >> - >> -#else /* !PPC64 */ >> -static int >> -__ftrace_make_nop(struct module *mod, >> - struct dyn_ftrace *rec, unsigned long addr) >> -{ >> - ppc_inst_t op; >> - unsigned long ip = rec->ip; >> - unsigned long tramp, ptr; >> - >> - if (copy_from_kernel_nofault(, (void *)ip, MCOUNT_INSN_SIZE)) >> - return -EFAULT; >> - >> - /* Make sure that that this is still a 24bit jump */ >> - if (!is_bl_op(op)) { >> - pr_err("Not expected bl: opcode is %s\n", ppc_inst_as_str(op)); >> - return -EINVAL; >> - } >> - >> - /* lets find where the pointer goes */ >> - tramp = find_bl_target(ip, op); >> - >> - /* Find where the trampoline jumps to */ >> - if (module_trampoline_target(mod, tramp, )) { >> - pr_err("Failed to get trampoline target\n"); >> - return -EFAULT; >> - } >> - >> - if (ptr != addr) { >> - pr_err("Trampoline location %08lx does not match addr\n", >> - tramp); >> - return -EINVAL; >> - } >> - >> - op = ppc_inst(PPC_RAW_NOP()); >> - >> - if (patch_instruction((u32 *)ip, op)) >> - return -EPERM; >> - >> - return 0; >> -} >> -#endif /* PPC64 */ >> #endif /* CONFIG_MODULES */ >> >> static unsigned long find_ftrace_tramp(unsigned long ip) >> @@ -437,13 +396,12 @@ int ftrace_make_nop(struct module *mod, >> } >> >> #ifdef CONFIG_MODULES >> -#ifdef CONFIG_PPC64 >> /* >> * Examine the existing instructions for __ftrace_make_call. >> * They should effectively be a NOP, and follow formal constraints, >> * depending on the ABI. Return false if they don't. >> */ >> -#ifndef CONFIG_MPROFILE_KERNEL >> +#ifndef CONFIG_DYNAMIC_FTRACE_WITH_REGS > > It is better to gate this on PPC64_ELF_ABI_v1 Ok I do that with the new CONFIG_PPC64_ELF_ABI_V1. > >> static int >> expected_nop_sequence(void *ip, ppc_inst_t op0, ppc_inst_t op1) >> { >> @@ -465,7 +423,7 @@ expected_nop_sequence(void *ip, ppc_inst_t op0, >> ppc_inst_t op1) >> static int >> expected_nop_sequence(void *ip, ppc_inst_t op0, ppc_inst_t op1) >> { >> - /* look for patched "NOP" on ppc64 with -mprofile-kernel */ >> + /* look for patched "NOP" on ppc64 with -mprofile-kernel or ppc32 */ >> if (!ppc_inst_equal(op0, ppc_inst(PPC_RAW_NOP( >> return 0; >> return 1; >> @@ -484,8 +442,10 @@ __ftrace_make_call(struct dyn_ftrace *rec, >> unsigned long addr) >> if (copy_inst_from_kernel_nofault(op, ip)) >> return -EFAULT; >> >> +#ifndef CONFIG_DYNAMIC_FTRACE_WITH_REGS >> if (copy_inst_from_kernel_nofault(op + 1, ip + 4)) >> return -EFAULT; >> +#endif > > Here too... > Done Christophe
Re: [PATCH v1 10/22] powerpc/ftrace: Use CONFIG_FUNCTION_TRACER instead of CONFIG_DYNAMIC_FTRACE
Le 18/04/2022 à 09:00, Naveen N. Rao a écrit : > Christophe Leroy wrote: >> Since commit 0c0c52306f47 ("powerpc: Only support DYNAMIC_FTRACE not >> static"), CONFIG_DYNAMIC_FTRACE is always selected when >> CONFIG_FUNCTION_TRACER is selected. >> >> To avoid confusion and have the reader wonder what's happen when >> CONFIG_FUNCTION_TRACER is selected and CONFIG_DYNAMIC_FTRACE is not, >> use CONFIG_FUNCTION_TRACER in ifdefs instead of CONFIG_DYNAMIC_FTRACE. >> >> As CONFIG_FUNCTION_GRAPH_TRACER depends on CONFIG_FUNCTION_TRACER, >> ftrace.o doesn't need to appear for both symbols in Makefile. >> >> Then as ftrace.o is built only when CONFIG_FUNCTION_TRACER is selected > > and since it implies CONFIG_DYNAMIC_FTRACE, CONFIG_DYNAMIC_FTRACE is not > needed in ftrace.c Ok, added to the commit message > >> ifdef CONFIG_FUNCTION_TRACER is not needed in ftrace.c >> >> Signed-off-by: Christophe Leroy >> --- >> arch/powerpc/include/asm/book3s/32/pgtable.h | 2 +- >> arch/powerpc/include/asm/book3s/64/pgtable.h | 2 +- >> arch/powerpc/include/asm/module.h | 4 ++-- >> arch/powerpc/include/asm/nohash/pgtable.h | 2 +- >> arch/powerpc/kernel/module_32.c | 4 ++-- >> arch/powerpc/kernel/module_64.c | 6 +++--- >> arch/powerpc/kernel/trace/Makefile | 4 +--- >> arch/powerpc/kernel/trace/ftrace.c | 4 >> 8 files changed, 11 insertions(+), 17 deletions(-) >> >> diff --git a/arch/powerpc/include/asm/book3s/32/pgtable.h >> b/arch/powerpc/include/asm/book3s/32/pgtable.h >> index 772e00dc4ef1..992aed626eb4 100644 >> --- a/arch/powerpc/include/asm/book3s/32/pgtable.h >> +++ b/arch/powerpc/include/asm/book3s/32/pgtable.h >> @@ -124,7 +124,7 @@ static inline bool pte_user(pte_t pte) >> * on platforms where such control is possible. >> */ >> #if defined(CONFIG_KGDB) || defined(CONFIG_XMON) || >> defined(CONFIG_BDI_SWITCH) ||\ >> - defined(CONFIG_KPROBES) || defined(CONFIG_DYNAMIC_FTRACE) >> + defined(CONFIG_KPROBES) || defined(CONFIG_FUNCTION_TRACER) >> #define PAGE_KERNEL_TEXT PAGE_KERNEL_X >> #else >> #define PAGE_KERNEL_TEXT PAGE_KERNEL_ROX >> diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h >> b/arch/powerpc/include/asm/book3s/64/pgtable.h >> index 875730d5af40..cf01b609572f 100644 >> --- a/arch/powerpc/include/asm/book3s/64/pgtable.h >> +++ b/arch/powerpc/include/asm/book3s/64/pgtable.h >> @@ -169,7 +169,7 @@ >> * on platforms where such control is possible. >> */ >> #if defined(CONFIG_KGDB) || defined(CONFIG_XMON) || >> defined(CONFIG_BDI_SWITCH) || \ >> - defined(CONFIG_KPROBES) || defined(CONFIG_DYNAMIC_FTRACE) >> + defined(CONFIG_KPROBES) || defined(CONFIG_FUNCTION_TRACER) >> #define PAGE_KERNEL_TEXT PAGE_KERNEL_X >> #else >> #define PAGE_KERNEL_TEXT PAGE_KERNEL_ROX >> diff --git a/arch/powerpc/include/asm/module.h >> b/arch/powerpc/include/asm/module.h >> index 857d9ff24295..e6f5963fd96e 100644 >> --- a/arch/powerpc/include/asm/module.h >> +++ b/arch/powerpc/include/asm/module.h >> @@ -39,7 +39,7 @@ struct mod_arch_specific { >> unsigned int init_plt_section; >> #endif /* powerpc64 */ >> >> -#ifdef CONFIG_DYNAMIC_FTRACE >> +#ifdef CONFIG_FUNCTION_TRACER >> unsigned long tramp; >> #ifdef CONFIG_DYNAMIC_FTRACE_WITH_REGS >> unsigned long tramp_regs; >> @@ -68,7 +68,7 @@ struct mod_arch_specific { >> # endif /* MODULE */ >> #endif >> >> -#ifdef CONFIG_DYNAMIC_FTRACE >> +#ifdef CONFIG_FUNCTION_TRACER >> # ifdef MODULE >> asm(".section .ftrace.tramp,\"ax\",@nobits; .align 3; .previous"); >> # endif /* MODULE */ >> diff --git a/arch/powerpc/include/asm/nohash/pgtable.h >> b/arch/powerpc/include/asm/nohash/pgtable.h >> index ac75f4ab0dba..2e8cf217a191 100644 >> --- a/arch/powerpc/include/asm/nohash/pgtable.h >> +++ b/arch/powerpc/include/asm/nohash/pgtable.h >> @@ -23,7 +23,7 @@ >> * on platforms where such control is possible. >> */ >> #if defined(CONFIG_KGDB) || defined(CONFIG_XMON) || >> defined(CONFIG_BDI_SWITCH) ||\ >> - defined(CONFIG_KPROBES) || defined(CONFIG_DYNAMIC_FTRACE) >> + defined(CONFIG_KPROBES) || defined(CONFIG_FUNCTION_TRACER) >> #define PAGE_KERNEL_TEXT PAGE_KERNEL_X >> #else >> #define PAGE_KERNEL_TEXT PAGE_KERNEL_ROX >> diff --git a/arch/powerpc/kernel/module_32.c >> b/arch/powerpc/kernel/module_32.c >> index a0432ef46967..2aa368ce21c9 100644 >> --- a/arch/powerpc/kernel/module_32.c >> +++ b/arch/powerpc/kernel/module_32.c >> @@ -39,7 +39,7 @@ static unsigned int count_relocs(const Elf32_Rela >> *rela, unsigned int num) >> r_addend = rela[i].r_addend; >> } >> >> -#ifdef CONFIG_DYNAMIC_FTRACE >> +#ifdef CONFIG_FUNCTION_TRACER >> _count_relocs++; /* add one for ftrace_caller */ >> #endif >> return _count_relocs; >> @@ -288,7 +288,7 @@ int apply_relocate_add(Elf32_Shdr *sechdrs, >> return 0; >> } >> >> -#ifdef CONFIG_DYNAMIC_FTRACE >> +#ifdef CONFIG_FUNCTION_TRACER >> int
Re: [RFC v2 01/39] Kconfig: introduce HAS_IOPORT option and select it as necessary
On Fri, May 6, 2022 at 12:20 PM Maciej W. Rozycki wrote: > On Thu, 5 May 2022, Arnd Bergmann wrote: > I think I'm missing something here. IIUC we're talking about a PCI/PCIe > bus used with s390 hardware, right? > > (It has to be PCI/PCIe, because other than x86/IA-64 host buses there are > only PCI/PCIe and EISA/ISA buses out there that define I/O access cycles > and EISA/ISA have long been obsoleted except perhaps from some niche use.) > > If this is PCI/PCIe indeed, then an I/O access is just a different bit > pattern put on the bus/in the TLP in the address phase. So what is there > inherent to the s390 architecture that prevents that different bit pattern > from being used? The hardware design for PCI on s390 is very different from any other architecture, and more abstract. Rather than implementing MMIO register access as pointer dereference, this is a separate CPU instruction that takes a device/bar plus offset as arguments rather than a pointer, and Linux encodes this back into a fake __iomem token. > If anything, I could imagine the same limitation as with current POWER9 > implementations, that is whatever glue is used to wire PCI/PCIe to the > rest of the system does not implement a way to use said bit pattern (which > has nothing to do with the POWER9 processor instruction set). > > But that has nothing to do with the presence or absence of any specific > processor instructions. It's just a limitation of bus glue. So I guess > it's just that all PCI/PCIe glue logic implementations for s390 have such > a limitation, right? There are separate instructions for PCI memory and config space, but no instructions for I/O space, or for non-PCI MMIO that it could be mapped into. Arnd
Re: [RFC v2 01/39] Kconfig: introduce HAS_IOPORT option and select it as necessary
On Fri, 2022-05-06 at 19:12 +1000, Finn Thain wrote: > > On Thu, 5 May 2022, Bjorn Helgaas wrote: > > > On Thu, May 05, 2022 at 07:39:42PM +0200, Arnd Bergmann wrote: > > > On Thu, May 5, 2022 at 6:10 PM Bjorn Helgaas wrote: > > > > On Wed, May 04, 2022 at 11:31:28PM +0200, Arnd Bergmann wrote: > > > > > The main goal is to avoid c), which is what happens on s390, but > > > > > can also happen elsewhere. Catching b) would be nice as well, > > > > > but is much harder to do from generic code as you'd need an > > > > > architecture specific inline asm statement to insert a ex_table > > > > > fixup, or a runtime conditional on each access. > > > > > > > > Or s390 could implement its own inb(). > > > > > > > > I'm hearing that generic powerpc kernels have to run both on machines > > > > that have I/O port space and those that don't. That makes me think > > > > s390 could do something similar. > > > > > > No, this is actually the current situation, and it makes absolutely no > > > sense. s390 has no way of implementing inb()/outb() because there > > > are no instructions for it and it cannot tunnel them through a virtual > > > address mapping like on most of the other architectures. (it has special > > > instructions for accessing memory space, which is not the same as > > > a pointer dereference here). > > > > > > The existing implementation gets flagged as a NULL pointer dereference > > > by a compiler warning because it effectively is. > > > > I think s390 currently uses the inb() in asm-generic/io.h, i.e., > > "__raw_readb(PCI_IOBASE + addr)". I understand that's a NULL pointer > > dereference because the default PCI_IOBASE is 0. > > > > I mooted a s390 inb() implementation like "return ~0" because that's > > what happens on most arches when there's no device to respond to the > > inb(). > > > > The HAS_IOPORT dependencies are fairly ugly IMHO, and they clutter > > drivers that use I/O ports in some cases but not others. But maybe > > it's the most practical way. > > > > Do you mean, "the most practical way to avoid a compiler warning on s390"? > What about "#pragma GCC diagnostic ignored"? This actually happens with clang. Apart from that, I think this would also fall under the same argument as the original patch Linus unpulled. We would just paint over someting that we know at compile time won't work: https://lore.kernel.org/lkml/CAHk-=wg80je=k7madf4e7wrrnp37e3qh6y10svhdc7o8sz_...@mail.gmail.com/
Re: [PATCH] crypto: vmx - Align the short log with Makefile cleanups
On Sun, May 01, 2022 at 10:07:49PM +0900, Masahiro Yamada wrote: > I notieced the log is not properly aligned: > > PERL drivers/crypto/vmx/aesp8-ppc.S > CC [M] fs/xfs/xfs_reflink.o > PERL drivers/crypto/vmx/ghashp8-ppc.S > CC [M] drivers/crypto/vmx/aes.o > > Add some spaces after 'PERL'. > > While I was here, I cleaned up the Makefile: > > - Merge the two similar rules > > - Remove redundant 'clean-files' (Having 'targets' is enough) > > - Move the flavour into the build command > > This still avoids the build failures fixed by commit 4ee812f6143d > ("crypto: vmx - Avoid weird build failures"). > > Signed-off-by: Masahiro Yamada > --- > > drivers/crypto/vmx/Makefile | 17 +++-- > 1 file changed, 3 insertions(+), 14 deletions(-) Patch applied. Thanks. -- Email: Herbert Xu Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
Re: [PATCH] bug: Use normal relative pointers in 'struct bug_entry'
On Thu, May 05, 2022 at 06:09:45PM -0700, Josh Poimboeuf wrote: > With CONFIG_GENERIC_BUG_RELATIVE_POINTERS, the addr/file relative > pointers are calculated weirdly: based on the beginning of the bug_entry > struct address, rather than their respective pointer addresses. > > Make the relative pointers less surprising to both humans and tools by > calculating them the normal way. > > Signed-off-by: Josh Poimboeuf This looks good to me. Just in case, I gave this a spin on arm64 defconfig atop v5.18-rc4. This builds cleanly with both GCC 11.1.0 and LLVM 14.0.0, and works correctly in testing on both with the LKDTM BUG/WARNING/WARNING_MESSAGE tests, i.e. echo WARNING > /sys/kernel/debug/provoke-crash/DIRECT echo WARNING_MESSAGE > /sys/kernel/debug/provoke-crash/DIRECT echo BUG > /sys/kernel/debug/provoke-crash/DIRECT FWIW: Reviewed-by: Mark Rutland Tested-by: Mark Rutland [arm64] As an aside (and for anyone else trying to duplicate my results), on arm64 there's a latent issue (prior to this patch) where BUG() will always result in a WARN_ON_ONCE() in rcu_eqs_enter(). Since BUG() uses a BRK, and we treat the BRK exception as an NMI, when we kill the task we do that in NMI context, but schedule another task in regular task context, and RCU doesn't like that: # echo BUG > /sys/kernel/debug/provoke-crash/DIRECT [ 28.284180] lkdtm: Performing direct entry BUG [ 28.285052] [ cut here ] [ 28.285940] kernel BUG at drivers/misc/lkdtm/bugs.c:78! [ 28.287008] Internal error: Oops - BUG: 0 [#1] PREEMPT SMP [ 28.288143] Modules linked in: [ 28.288798] CPU: 0 PID: 151 Comm: bash Not tainted 5.18.0-rc4 #1 [ 28.290040] Hardware name: linux,dummy-virt (DT) [ 28.290979] pstate: 6045 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--) [ 28.292380] pc : lkdtm_BUG+0x4/0xc [ 28.293084] lr : lkdtm_do_action+0x24/0x30 [ 28.293923] sp : 883bbce0 [ 28.294624] x29: 883bbce0 x28: 3c574344 x27: [ 28.296057] x26: x25: a4bc19c480b0 x24: 883bbdf0 [ 28.297493] x23: 0004 x22: 3c57440f3000 x21: a4bc1a0bfba0 [ 28.298933] x20: a4bc19c480c0 x19: 0001 x18: [ 28.300369] x17: x16: x15: 0720072007200720 [ 28.301823] x14: 0720072007200747 x13: a4bc1a8d2520 x12: 03b1 [ 28.303257] x11: 013b x10: a4bc1a92a520 x9 : a4bc1a8d2520 [ 28.304689] x8 : efff x7 : a4bc1a92a520 x6 : [ 28.306120] x5 : x4 : 3c57bfbcc9e8 x3 : [ 28.307550] x2 : x1 : 3c574344 x0 : a4bc19279284 [ 28.308981] Call trace: [ 28.309496] lkdtm_BUG+0x4/0xc [ 28.310134] direct_entry+0x11c/0x1cc [ 28.310888] full_proxy_write+0x60/0xbc [ 28.311690] vfs_write+0xc4/0x2a4 [ 28.312383] ksys_write+0x68/0xf4 [ 28.313056] __arm64_sys_write+0x20/0x2c [ 28.313851] invoke_syscall+0x48/0x114 [ 28.314623] el0_svc_common.constprop.0+0xd4/0xfc [ 28.315584] do_el0_svc+0x28/0x90 [ 28.316276] el0_svc+0x34/0xb0 [ 28.316917] el0t_64_sync_handler+0xa4/0x130 [ 28.317786] el0t_64_sync+0x18c/0x190 [ 28.318560] Code: b90027e0 17ea 941b4d4c d503245f (d421) [ 28.319796] ---[ end trace ]--- [ 28.320736] note: bash[151] exited with preempt_count 1 [ 28.329377] [ cut here ] [ 28.330327] WARNING: CPU: 0 PID: 0 at kernel/rcu/tree.c:624 rcu_eqs_enter.constprop.0+0x7c/0x84 [ 28.332103] Modules linked in: [ 28.332757] CPU: 0 PID: 0 Comm: swapper/0 Tainted: G D 5.18.0-rc4 #1 [ 28.334355] Hardware name: linux,dummy-virt (DT) [ 28.335318] pstate: 204000c5 (nzCv daIF +PAN -UAO -TCO -DIT -SSBS BTYPE=--) [ 28.336745] pc : rcu_eqs_enter.constprop.0+0x7c/0x84 [ 28.337766] lr : rcu_idle_enter+0x10/0x1c [ 28.338609] sp : a4bc1a8b3d40 [ 28.339309] x29: a4bc1a8b3d40 x28: 41168458 x27: [ 28.340788] x26: a4bc1a8c3340 x25: x24: [ 28.342255] x23: a4bc1a8b9b4c x22: a4bc1a37a6f8 x21: a4bc1a8b9a38 [ 28.343705] x20: a4bc1a8b9b40 x19: 3c57bfbd4800 x18: [ 28.345159] x17: x16: x15: 06a1d2912376 [ 28.346632] x14: 018a x13: 018a x12: [ 28.348089] x11: 0001 x10: 0a50 x9 : a4bc1a8b3ce0 [ 28.349551] x8 : a4bc1a8c3df0 x7 : 3c57bfbd3b80 x6 : 000154de2486 [ 28.351040] x5 : 03ff x4 : 0a5c x3 : a4bc1a8b79c0 [ 28.352505] x2 : 0a5c x1 : 4002 x0 : 4000 [ 28.353966] Call trace: [ 28.354496] rcu_eqs_enter.constprop.0+0x7c/0x84 [ 28.355467] rcu_idle_enter+0x10/0x1c [ 28.356230] default_idle_call+0x20/0x6c [ 28.357061] do_idle+0x22c/0x29c [ 28.357743]
Re: [RFC v2 01/39] Kconfig: introduce HAS_IOPORT option and select it as necessary
On Thu, 5 May 2022, Arnd Bergmann wrote: > > I'm hearing that generic powerpc kernels have to run both on machines > > that have I/O port space and those that don't. That makes me think > > s390 could do something similar. > > No, this is actually the current situation, and it makes absolutely no > sense. s390 has no way of implementing inb()/outb() because there > are no instructions for it and it cannot tunnel them through a virtual > address mapping like on most of the other architectures. (it has special > instructions for accessing memory space, which is not the same as > a pointer dereference here). I think I'm missing something here. IIUC we're talking about a PCI/PCIe bus used with s390 hardware, right? (It has to be PCI/PCIe, because other than x86/IA-64 host buses there are only PCI/PCIe and EISA/ISA buses out there that define I/O access cycles and EISA/ISA have long been obsoleted except perhaps from some niche use.) If this is PCI/PCIe indeed, then an I/O access is just a different bit pattern put on the bus/in the TLP in the address phase. So what is there inherent to the s390 architecture that prevents that different bit pattern from being used? If anything, I could imagine the same limitation as with current POWER9 implementations, that is whatever glue is used to wire PCI/PCIe to the rest of the system does not implement a way to use said bit pattern (which has nothing to do with the POWER9 processor instruction set). But that has nothing to do with the presence or absence of any specific processor instructions. It's just a limitation of bus glue. So I guess it's just that all PCI/PCIe glue logic implementations for s390 have such a limitation, right? Maciej
Re: [RFC v2 01/39] Kconfig: introduce HAS_IOPORT option and select it as necessary
On Thu, 2022-05-05 at 14:53 -0500, Bjorn Helgaas wrote: > On Thu, May 05, 2022 at 07:39:42PM +0200, Arnd Bergmann wrote: > > On Thu, May 5, 2022 at 6:10 PM Bjorn Helgaas wrote: > > > On Wed, May 04, 2022 at 11:31:28PM +0200, Arnd Bergmann wrote: > > > > The main goal is to avoid c), which is what happens on s390, but > > > > can also happen elsewhere. Catching b) would be nice as well, > > > > but is much harder to do from generic code as you'd need an > > > > architecture specific inline asm statement to insert a ex_table > > > > fixup, or a runtime conditional on each access. > > > > > > Or s390 could implement its own inb(). > > > > > > I'm hearing that generic powerpc kernels have to run both on machines > > > that have I/O port space and those that don't. That makes me think > > > s390 could do something similar. > > > > No, this is actually the current situation, and it makes absolutely no > > sense. s390 has no way of implementing inb()/outb() because there > > are no instructions for it and it cannot tunnel them through a virtual > > address mapping like on most of the other architectures. (it has special > > instructions for accessing memory space, which is not the same as > > a pointer dereference here). > > > > The existing implementation gets flagged as a NULL pointer dereference > > by a compiler warning because it effectively is. > > I think s390 currently uses the inb() in asm-generic/io.h, i.e., > "__raw_readb(PCI_IOBASE + addr)". I understand that's a NULL pointer > dereference because the default PCI_IOBASE is 0. > > I mooted a s390 inb() implementation like "return ~0" because that's > what happens on most arches when there's no device to respond to the > inb(). > > The HAS_IOPORT dependencies are fairly ugly IMHO, and they clutter > drivers that use I/O ports in some cases but not others. But maybe > it's the most practical way. > > Bjorn I fear such stubs are kind of equivalent to my previous patch doing the same in asm-generic/io.h that was pulled and then unpulled by Linus. Maybe it would be slightly different if instead of a warning outX() would just be a NOP and inX() just returned ~0 but we're in essence pretending that we have these functions when we know they are nonsense. Another argument I see is that as shown by POWER9 we might start to see more platforms that just can't do I/O port access. E.g. I would also be surprised if Apple's M1 has I/O port access. Sooner or later I expect distributions on some platforms to only support such systems. For example on ppc a server distribution might only support IBM POWER without I/O port support before too long. Then having HAS_IOPORT allows to get rid of drivers that won't work anyway. There are also reports of probing a driver with I/O ports causing a system crash on systems without I/O port support. For example in this answer by John Garry (added so he may supply more information): https://lore.kernel.org/lkml/db043b76-880d-5fad-69cf-96abcd9cd...@huawei.com/
Re: [PATCH] powerpc/papr_scm: Fix buffer overflow issue with CONFIG_FORTIFY_SOURCE
Hi Kajol, Thanks for the patch. Minor review comment below: Kajol Jain writes: > With CONFIG_FORTIFY_SOURCE enabled, string functions will also perform > dynamic checks for string size which can panic the kernel, > like incase of overflow detection. > > In papr_scm, papr_scm_pmu_check_events function uses stat->stat_id > with string operations, to populate the nvdimm_events_map array. > Since stat_id variable is not NULL terminated, the kernel panics > with CONFIG_FORTIFY_SOURCE enabled at boot time. > > Below are the logs of kernel panic: > > [0.090221][T1] detected buffer overflow in __fortify_strlen > [0.090241][T1] [ cut here ] > [0.090246][T1] kernel BUG at lib/string_helpers.c:980! > [0.090253][T1] Oops: Exception in kernel mode, sig: 5 [#1] > > [0.090375][T1] NIP [c077dad0] fortify_panic+0x28/0x38 > [0.090382][T1] LR [c077dacc] fortify_panic+0x24/0x38 > [0.090387][T1] Call Trace: > [0.090390][T1] [c022d77836e0] [c077dacc] > fortify_panic+0x24/0x38 (unreliable) > [9.297707] [T1] [c0080deb2660] > papr_scm_pmu_check_events.constprop.0+0x118/0x220 [papr_scm] > [9.297721] [T1] [c0080deb2cb0] papr_scm_probe+0x288/0x62c > [papr_scm] > [9.297732] [T1] [c09b46a8] platform_probe+0x98/0x150 > > Fix this issue by using kmemdup_nul function to copy the content of > stat->stat_id directly to the nvdimm_events_map array. > > Fixes: 4c08d4bbc089 ("powerpc/papr_scm: Add perf interface support") > Signed-off-by: Kajol Jain > --- > arch/powerpc/platforms/pseries/papr_scm.c | 7 ++- > 1 file changed, 2 insertions(+), 5 deletions(-) > > diff --git a/arch/powerpc/platforms/pseries/papr_scm.c > b/arch/powerpc/platforms/pseries/papr_scm.c > index f58728d5f10d..39962c905542 100644 > --- a/arch/powerpc/platforms/pseries/papr_scm.c > +++ b/arch/powerpc/platforms/pseries/papr_scm.c > @@ -462,7 +462,6 @@ static int papr_scm_pmu_check_events(struct papr_scm_priv > *p, struct nvdimm_pmu > { > struct papr_scm_perf_stat *stat; > struct papr_scm_perf_stats *stats; > - char *statid; > int index, rc, count; > u32 available_events; > > @@ -493,14 +492,12 @@ static int papr_scm_pmu_check_events(struct > papr_scm_priv *p, struct nvdimm_pmu > > for (index = 0, stat = stats->scm_statistic, count = 0; >index < available_events; index++, ++stat) { > - statid = kzalloc(strlen(stat->stat_id) + 1, GFP_KERNEL); > - if (!statid) { > + p->nvdimm_events_map[count] = kmemdup_nul(stat->stat_id, > 8, GFP_KERNEL); s/8/sizeof(stat->stat_id)/ > + if (!p->nvdimm_events_map[count]) { > rc = -ENOMEM; > goto out_nvdimm_events_map; > } > > - strcpy(statid, stat->stat_id); > - p->nvdimm_events_map[count] = statid; > count++; > } > p->nvdimm_events_map[count] = NULL; > -- > 2.31.1 > -- Cheers ~ Vaibhav
Re: [PATCH] tools/perf/tests: Skip perf BPF test if clang is not present
> On 05-May-2022, at 10:51 PM, Arnaldo Carvalho de Melo wrote: > > Em Thu, May 05, 2022 at 03:30:39PM +0530, Athira Rajeev escreveu: >> Perf BPF filter test fails in environment where "clang" >> is not installed. >> >> Test failure logs: >> >> <<>> >> 42: BPF filter: >> 42.1: Basic BPF filtering : Skip >> 42.2: BPF pinning : FAILED! >> 42.3: BPF prologue generation : FAILED! >> <<>> >> >> Enabling verbose option provided debug logs which says >> clang/llvm needs to be installed. Snippet of verbose logs: >> >> <<>> >> 42.2: BPF pinning : >> --- start --- >> test child forked, pid 61423 >> ERROR: unable to find clang. >> Hint:Try to install latest clang/llvm to support BPF. >>Check your $PATH >> >> <> >> >> Failed to compile test case: 'Basic BPF llvm compile' >> Unable to get BPF object, fix kbuild first >> test child finished with -1 >> end >> BPF filter subtest 2: FAILED! >> <<>> >> >> Here subtests, "BPF pinning" and "BPF prologue generation" >> failed and logs shows clang/llvm is needed. After installing >> clang, testcase passes. >> >> Reason on why subtest failure happens though logs has proper >> debug information: >> Main function __test__bpf calls test_llvm__fetch_bpf_obj by >> passing 4th argument as true ( 4th arguments maps to parameter >> "force" in test_llvm__fetch_bpf_obj ). But this will cause >> test_llvm__fetch_bpf_obj to skip the check for clang/llvm. >> >> Snippet of code part which checks for clang based on >> parameter "force" in test_llvm__fetch_bpf_obj: >> >> <<>> >> if (!force && (!llvm_param.user_set_param && >> <<>> >> >> Since force is set to "false", test won't get skipped and >> fails to compile test case. The BPF code compilation needs >> clang, So pass the fourth argument as "false" and also skip >> the test if reason for return is "TEST_SKIP" >> >> After the patch: >> >> <<>> >> 42: BPF filter: >> 42.1: Basic BPF filtering : Skip >> 42.2: BPF pinning : Skip >> 42.3: BPF prologue generation : Skip >> <<>> > > Wouldn't it be better to add the reason for the skip, like other tests > do? > > E.g.: > > 23: Watchpoint : > 23.1: Read Only Watchpoint : Skip > (missing hardware support) > 23.2: Write Only Watchpoint : Ok > 23.3: Read / Write Watchpoint : Ok > 23.4: Modify Watchpoint > > Something like: > > After the patch: > > <<>> > 42: BPF filter: > 42.1: Basic BPF filtering : Skip (clang not installed) > 42.2: BPF pinning : Skip (clang not installed) > 42.3: BPF prologue generation : Skip (clang not installed) Hi Arnaldo, I tried to use TEST_CASE_REASON("BPF pinning", bpf_pinning, "clang not installed") The clang check is done in test_llvm__fetch_bpf_obj under some condition checks: <<>> /* * Skip this test if user's .perfconfig doesn't set [llvm] section * and clang is not found in $PATH */ if (!force && (!llvm_param.user_set_param && llvm__search_clang())) { pr_debug("No clang, skip this test\n"); return TEST_SKIP; } <<>> But the reason for BPF skip could happen at other places also ie non-root user, bpf support checks from check_env. So can't exactly print the skip reason to be clang since It could get skipped from other environment checks too. Any suggestions Arnaldo ? Thanks Athira > <<>> > >> Signed-off-by: Athira Rajeev >> --- >> tools/perf/tests/bpf.c | 4 ++-- >> 1 file changed, 2 insertions(+), 2 deletions(-) >> >> diff --git a/tools/perf/tests/bpf.c b/tools/perf/tests/bpf.c >> index 57b9591f7cbb..ae62f01239e3 100644 >> --- a/tools/perf/tests/bpf.c >> +++ b/tools/perf/tests/bpf.c >> @@ -222,11 +222,11 @@ static int __test__bpf(int idx) >> >> ret = test_llvm__fetch_bpf_obj(_buf, _buf_sz, >> bpf_testcase_table[idx].prog_id, >> - true, NULL); >> + false, NULL); >> if (ret != TEST_OK || !obj_buf || !obj_buf_sz) { >> pr_debug("Unable to get BPF object, %s\n", >> bpf_testcase_table[idx].msg_compile_fail); >> -if (idx == 0) >> +if ((idx == 0) || (ret == TEST_SKIP)) >> return TEST_SKIP; >> else >> return TEST_FAIL; >> -- >> 2.35.1 > > -- > > - Arnaldo
Re: [PATCH V2 1/2] tools/perf: Add utility function to read /proc/cpuinfo for any field
> On 05-May-2022, at 10:54 PM, Arnaldo Carvalho de Melo wrote: > > Em Thu, May 05, 2022 at 03:09:59PM +0530, Athira Rajeev escreveu: >> /proc/cpuinfo provides information about type of processor, number >> of CPU's etc. Reading /proc/cpuinfo file outputs useful information >> by field name like cpu, platform, model (depending on architecture) >> and its value separated by colon. >> >> Add new utility function "cpuinfo_field" in "util/header.c" which >> accepts field name as input string to search in /proc/cpuinfo content. >> This returns the first matching value as resulting string. Example, >> calling the function "cpuinfo_field(platform)" in powerpc returns >> the platform value. This can be used to fetch processor information >> from "cpuinfo" by other utilities/testcases. >> >> Signed-off-by: Athira Rajeev >> --- >> tools/perf/util/header.c | 53 >> tools/perf/util/header.h | 1 + >> 2 files changed, 54 insertions(+) >> >> diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c >> index a27132e5a5ef..f08857f96606 100644 >> --- a/tools/perf/util/header.c >> +++ b/tools/perf/util/header.c >> @@ -983,6 +983,59 @@ static int write_dir_format(struct feat_fd *ff, >> return do_write(ff, >dir.version, sizeof(data->dir.version)); >> } >> >> +/* >> + * Return entry from /proc/cpuinfo >> + * indicated by "search" parameter. >> + */ >> +char *cpuinfo_field(const char *search) >> +{ >> +FILE *file; >> +char *buf = NULL; >> +char *copy_buf = NULL, *p; >> +size_t len = 0; >> + >> +if (!search) >> +return NULL; >> + >> +file = fopen("/proc/cpuinfo", "r"); >> +if (!file) >> +return NULL; >> + >> +while (getline(, , file) > 0) { >> +if (!strncmp(buf, search, strlen(search))) > > Can you save the search string lenght in a variable and use it instead > of calling strlen() for the same buffer for each line in /proc/cpuinfo? Hi Arnaldo, Michael Thanks for review comments. Based on suggestion from Michael, I am reworking on patch 2 to SKIP the test if physical_id is set to -1 irrespective of value from cpuinfo. In this patch, I had written "cpuinfo_field " function as generic function for retrieving any entry from /proc/cpuinfo. But it won't be used in patch 2 now. Do you think this function is useful to keep ? Otherwise, I will drop patch 1 Thanks Athira Rajeev > >> +break; >> +} >> + >> +if (feof(file)) >> +goto done; >> + >> +/* >> + * Trim the new line and separate >> + * value for search field from ":" >> + * in cpuinfo line output. >> + * Example output line: >> + * platform : >> + */ >> +copy_buf = buf; >> +p = strchr(copy_buf, ':'); > > So you assume that this will always be there, right? Shouldn't we not > assume that and check if p is NULL and bail out instead? > >> + >> +/* Go to string after ":" */ >> +copy_buf = p + 1; >> +p = strchr(copy_buf, '\n'); > > Ditto. > >> +if (p) >> +*p = '\0'; >> + >> +/* Copy the filtered string after removing space to buf */ >> +strcpy(buf, strim(copy_buf)); >> + >> +fclose(file); >> +return buf; >> + >> +done: > > Please rename this goto label to "not_found", "done" isn't intention > revealing. > >> +free(buf); >> +fclose(file); >> +return NULL; >> +} >> /* >> * Check whether a CPU is online >> * >> diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h >> index 0eb4bc29a5a4..b0f754364bd4 100644 >> --- a/tools/perf/util/header.h >> +++ b/tools/perf/util/header.h >> @@ -166,4 +166,5 @@ int get_cpuid(char *buffer, size_t sz); >> >> char *get_cpuid_str(struct perf_pmu *pmu __maybe_unused); >> int strcmp_cpuid_str(const char *s1, const char *s2); >> +char *cpuinfo_field(const char *search); >> #endif /* __PERF_HEADER_H */ >> -- >> 2.35.1 > > -- > > - Arnaldo
Re: [PATCH] bug: Use normal relative pointers in 'struct bug_entry'
Josh Poimboeuf writes: > With CONFIG_GENERIC_BUG_RELATIVE_POINTERS, the addr/file relative > pointers are calculated weirdly: based on the beginning of the bug_entry > struct address, rather than their respective pointer addresses. > > Make the relative pointers less surprising to both humans and tools by > calculating them the normal way. > > Signed-off-by: Josh Poimboeuf Acked-by: Sven Schnelle # s390 > --- > arch/arm64/include/asm/asm-bug.h | 4 ++-- > arch/powerpc/include/asm/bug.h | 5 +++-- > arch/riscv/include/asm/bug.h | 4 ++-- > arch/s390/include/asm/bug.h | 5 +++-- > arch/x86/include/asm/bug.h | 2 +- > lib/bug.c| 15 +++ > 6 files changed, 18 insertions(+), 17 deletions(-) > > diff --git a/arch/arm64/include/asm/asm-bug.h > b/arch/arm64/include/asm/asm-bug.h > index 03f52f84a4f3..c762038ba400 100644 > --- a/arch/arm64/include/asm/asm-bug.h > +++ b/arch/arm64/include/asm/asm-bug.h > @@ -14,7 +14,7 @@ > 14472: .string file; \ > .popsection;\ > \ > - .long 14472b - 14470b; \ > + .long 14472b - .; \ > .short line; > #else > #define _BUGVERBOSE_LOCATION(file, line) > @@ -25,7 +25,7 @@ > #define __BUG_ENTRY(flags) \ > .pushsection __bug_table,"aw"; \ > .align 2; \ > - 14470: .long 14471f - 14470b; \ > + 14470: .long 14471f - .; \ > _BUGVERBOSE_LOCATION(__FILE__, __LINE__) \ > .short flags; \ > .popsection;\ > diff --git a/arch/powerpc/include/asm/bug.h b/arch/powerpc/include/asm/bug.h > index ecbae1832de3..76252576d889 100644 > --- a/arch/powerpc/include/asm/bug.h > +++ b/arch/powerpc/include/asm/bug.h > @@ -13,7 +13,8 @@ > #ifdef CONFIG_DEBUG_BUGVERBOSE > .macro __EMIT_BUG_ENTRY addr,file,line,flags >.section __bug_table,"aw" > -5001: .4byte \addr - 5001b, 5002f - 5001b > +5001: .4byte \addr - . > + .4byte 5002f - . >.short \line, \flags >.org 5001b+BUG_ENTRY_SIZE >.previous > @@ -24,7 +25,7 @@ > #else > .macro __EMIT_BUG_ENTRY addr,file,line,flags >.section __bug_table,"aw" > -5001: .4byte \addr - 5001b > +5001: .4byte \addr - . >.short \flags >.org 5001b+BUG_ENTRY_SIZE >.previous > diff --git a/arch/riscv/include/asm/bug.h b/arch/riscv/include/asm/bug.h > index d3804a2f9aad..1aaea81fb141 100644 > --- a/arch/riscv/include/asm/bug.h > +++ b/arch/riscv/include/asm/bug.h > @@ -30,8 +30,8 @@ > typedef u32 bug_insn_t; > > #ifdef CONFIG_GENERIC_BUG_RELATIVE_POINTERS > -#define __BUG_ENTRY_ADDR RISCV_INT " 1b - 2b" > -#define __BUG_ENTRY_FILE RISCV_INT " %0 - 2b" > +#define __BUG_ENTRY_ADDR RISCV_INT " 1b - ." > +#define __BUG_ENTRY_FILE RISCV_INT " %0 - ." > #else > #define __BUG_ENTRY_ADDR RISCV_PTR " 1b" > #define __BUG_ENTRY_FILE RISCV_PTR " %0" > diff --git a/arch/s390/include/asm/bug.h b/arch/s390/include/asm/bug.h > index 0b25f28351ed..aebe1e22c7be 100644 > --- a/arch/s390/include/asm/bug.h > +++ b/arch/s390/include/asm/bug.h > @@ -15,7 +15,8 @@ > "1: .asciz \""__FILE__"\"\n" \ > ".previous\n" \ > ".section __bug_table,\"awM\",@progbits,%2\n" \ > - "2: .long 0b-2b,1b-2b\n" \ > + "2: .long 0b-.\n" \ > + " .long 1b-.\n" \ > " .short %0,%1\n"\ > " .org2b+%2\n"\ > ".previous\n" \ > @@ -30,7 +31,7 @@ > asm_inline volatile(\ > "0: mc 0,0\n" \ > ".section __bug_table,\"awM\",@progbits,%1\n" \ > - "1: .long 0b-1b\n"\ > + "1: .long 0b-.\n" \ > " .short %0\n" \ > " .org1b+%1\n"\ > ".previous\n" \ > diff --git a/arch/x86/include/asm/bug.h b/arch/x86/include/asm/bug.h > index aaf0cb0db4ae..a3ec87d198ac 100644 > --- a/arch/x86/include/asm/bug.h > +++ b/arch/x86/include/asm/bug.h > @@ -18,7 +18,7 @@ > #ifdef CONFIG_X86_32 > # define __BUG_REL(val) ".long " __stringify(val) > #else > -# define __BUG_REL(val) ".long " __stringify(val) " - 2b" > +#
[PATCH v1 1/2] powerpc: Include asm/firmware.h in all users of firmware_has_feature()
Trying to remove asm/ppc_asm.h from all places that don't need it leads to several failures linked to firmware_has_feature(). To fix it, include asm/firmware.h in all files using firmware_has_feature() All users found with: git grep -L "firmware\.h" ` git grep -l "firmware_has_feature("` Signed-off-by: Christophe Leroy --- arch/powerpc/include/asm/book3s/64/hugetlb.h | 3 +++ arch/powerpc/include/asm/cputime.h| 1 + arch/powerpc/include/asm/interrupt.h | 1 + arch/powerpc/include/asm/mman.h | 1 + arch/powerpc/include/asm/prom.h | 1 + arch/powerpc/kernel/dawr.c| 1 + arch/powerpc/kexec/core.c | 1 + arch/powerpc/kvm/book3s_64_mmu_radix.c| 1 + arch/powerpc/kvm/book3s_hv_nested.c | 1 + arch/powerpc/mm/book3s64/hash_pgtable.c | 1 + arch/powerpc/mm/book3s64/pkeys.c | 1 + arch/powerpc/mm/hugetlbpage.c | 1 + arch/powerpc/platforms/pseries/papr_platform_attributes.c | 1 + arch/powerpc/platforms/pseries/vas.c | 1 + 14 files changed, 16 insertions(+) diff --git a/arch/powerpc/include/asm/book3s/64/hugetlb.h b/arch/powerpc/include/asm/book3s/64/hugetlb.h index 12e150e615b7..1c42a0786290 100644 --- a/arch/powerpc/include/asm/book3s/64/hugetlb.h +++ b/arch/powerpc/include/asm/book3s/64/hugetlb.h @@ -1,6 +1,9 @@ /* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_POWERPC_BOOK3S_64_HUGETLB_H #define _ASM_POWERPC_BOOK3S_64_HUGETLB_H + +#include + /* * For radix we want generic code to handle hugetlb. But then if we want * both hash and radix to be enabled together we need to workaround the diff --git a/arch/powerpc/include/asm/cputime.h b/arch/powerpc/include/asm/cputime.h index 504f7fe6711a..6d2b27997492 100644 --- a/arch/powerpc/include/asm/cputime.h +++ b/arch/powerpc/include/asm/cputime.h @@ -19,6 +19,7 @@ #include #include #include +#include typedef u64 __nocast cputime_t; typedef u64 __nocast cputime64_t; diff --git a/arch/powerpc/include/asm/interrupt.h b/arch/powerpc/include/asm/interrupt.h index f964ef5c57d8..e8f6fd6b1cce 100644 --- a/arch/powerpc/include/asm/interrupt.h +++ b/arch/powerpc/include/asm/interrupt.h @@ -69,6 +69,7 @@ #include #include #include +#include #include #include #include diff --git a/arch/powerpc/include/asm/mman.h b/arch/powerpc/include/asm/mman.h index 7cb6d18f5cd6..699b3c5e144c 100644 --- a/arch/powerpc/include/asm/mman.h +++ b/arch/powerpc/include/asm/mman.h @@ -12,6 +12,7 @@ #include #include #include +#include static inline unsigned long arch_calc_vm_prot_bits(unsigned long prot, unsigned long pkey) diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h index 5c80152e8f18..6f109b5cb84e 100644 --- a/arch/powerpc/include/asm/prom.h +++ b/arch/powerpc/include/asm/prom.h @@ -14,6 +14,7 @@ #include #include #include +#include /* These includes should be removed once implicit includes are cleaned up. */ #include diff --git a/arch/powerpc/kernel/dawr.c b/arch/powerpc/kernel/dawr.c index 64e423d2fe0f..bb818ae85785 100644 --- a/arch/powerpc/kernel/dawr.c +++ b/arch/powerpc/kernel/dawr.c @@ -11,6 +11,7 @@ #include #include #include +#include bool dawr_force_enable; EXPORT_SYMBOL_GPL(dawr_force_enable); diff --git a/arch/powerpc/kexec/core.c b/arch/powerpc/kexec/core.c index abf5897ae88c..f0774ff3296f 100644 --- a/arch/powerpc/kexec/core.c +++ b/arch/powerpc/kexec/core.c @@ -20,6 +20,7 @@ #include #include #include +#include void machine_kexec_mask_interrupts(void) { unsigned int i; diff --git a/arch/powerpc/kvm/book3s_64_mmu_radix.c b/arch/powerpc/kvm/book3s_64_mmu_radix.c index 42851c32ff3b..9d4b3feda3b6 100644 --- a/arch/powerpc/kvm/book3s_64_mmu_radix.c +++ b/arch/powerpc/kvm/book3s_64_mmu_radix.c @@ -22,6 +22,7 @@ #include #include #include +#include /* * Supported radix tree geometry. diff --git a/arch/powerpc/kvm/book3s_hv_nested.c b/arch/powerpc/kvm/book3s_hv_nested.c index c943a051c6e7..fae06f4fbce1 100644 --- a/arch/powerpc/kvm/book3s_hv_nested.c +++ b/arch/powerpc/kvm/book3s_hv_nested.c @@ -20,6 +20,7 @@ #include #include #include +#include static struct patb_entry *pseries_partition_tb; diff --git a/arch/powerpc/mm/book3s64/hash_pgtable.c b/arch/powerpc/mm/book3s64/hash_pgtable.c index 7ce8914992e3..f1cadf771b40 100644 --- a/arch/powerpc/mm/book3s64/hash_pgtable.c +++ b/arch/powerpc/mm/book3s64/hash_pgtable.c @@ -13,6 +13,7 @@ #include #include #include +#include #include diff --git a/arch/powerpc/mm/book3s64/pkeys.c b/arch/powerpc/mm/book3s64/pkeys.c index 753e62ba67af..1d2675ab6711 100644 --- a/arch/powerpc/mm/book3s64/pkeys.c +++ b/arch/powerpc/mm/book3s64/pkeys.c @@ -10,6 +10,7 @@
[PATCH v1 2/2] powerpc: Don't include asm/ppc_asm.h in other headers
asm/ppc_asm.h is not needed in any of the header it is included. It is only needed by irq.c. Include it there and remove it from other headers. word-at-a-time.h only need ex_table.h, so include it instead. Signed-off-by: Christophe Leroy --- arch/powerpc/include/asm/io.h | 1 - arch/powerpc/include/asm/uaccess.h| 1 - arch/powerpc/include/asm/word-at-a-time.h | 2 +- arch/powerpc/kernel/irq.c | 1 + 4 files changed, 2 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/include/asm/io.h b/arch/powerpc/include/asm/io.h index fee979d3a1aa..6291af42533d 100644 --- a/arch/powerpc/include/asm/io.h +++ b/arch/powerpc/include/asm/io.h @@ -33,7 +33,6 @@ extern struct pci_dev *isa_bridge_pcidev; #include #include #include -#include #define SIO_CONFIG_RA 0x398 #define SIO_CONFIG_RD 0x399 diff --git a/arch/powerpc/include/asm/uaccess.h b/arch/powerpc/include/asm/uaccess.h index 9b82b38ff867..14a08806f8e8 100644 --- a/arch/powerpc/include/asm/uaccess.h +++ b/arch/powerpc/include/asm/uaccess.h @@ -2,7 +2,6 @@ #ifndef _ARCH_POWERPC_UACCESS_H #define _ARCH_POWERPC_UACCESS_H -#include #include #include #include diff --git a/arch/powerpc/include/asm/word-at-a-time.h b/arch/powerpc/include/asm/word-at-a-time.h index f3f4710d4ff5..46c31fb8748d 100644 --- a/arch/powerpc/include/asm/word-at-a-time.h +++ b/arch/powerpc/include/asm/word-at-a-time.h @@ -7,7 +7,7 @@ #include #include -#include +#include #ifdef __BIG_ENDIAN__ diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index 752fb182eacb..5f68d5e4243d 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c @@ -66,6 +66,7 @@ #include #include #include +#include #ifdef CONFIG_PPC64 #include -- 2.35.1
Re: [RFC v2 01/39] Kconfig: introduce HAS_IOPORT option and select it as necessary
On Thu, 5 May 2022, Bjorn Helgaas wrote: > On Thu, May 05, 2022 at 07:39:42PM +0200, Arnd Bergmann wrote: > > On Thu, May 5, 2022 at 6:10 PM Bjorn Helgaas wrote: > > > On Wed, May 04, 2022 at 11:31:28PM +0200, Arnd Bergmann wrote: > > > > > > > > The main goal is to avoid c), which is what happens on s390, but > > > > can also happen elsewhere. Catching b) would be nice as well, > > > > but is much harder to do from generic code as you'd need an > > > > architecture specific inline asm statement to insert a ex_table > > > > fixup, or a runtime conditional on each access. > > > > > > Or s390 could implement its own inb(). > > > > > > I'm hearing that generic powerpc kernels have to run both on machines > > > that have I/O port space and those that don't. That makes me think > > > s390 could do something similar. > > > > No, this is actually the current situation, and it makes absolutely no > > sense. s390 has no way of implementing inb()/outb() because there > > are no instructions for it and it cannot tunnel them through a virtual > > address mapping like on most of the other architectures. (it has special > > instructions for accessing memory space, which is not the same as > > a pointer dereference here). > > > > The existing implementation gets flagged as a NULL pointer dereference > > by a compiler warning because it effectively is. > > I think s390 currently uses the inb() in asm-generic/io.h, i.e., > "__raw_readb(PCI_IOBASE + addr)". I understand that's a NULL pointer > dereference because the default PCI_IOBASE is 0. > > I mooted a s390 inb() implementation like "return ~0" because that's > what happens on most arches when there's no device to respond to the > inb(). > > The HAS_IOPORT dependencies are fairly ugly IMHO, and they clutter > drivers that use I/O ports in some cases but not others. But maybe > it's the most practical way. > Do you mean, "the most practical way to avoid a compiler warning on s390"? What about "#pragma GCC diagnostic ignored"?
[PATCH 15/35] selftest/powerpc/pmu: Add support for perf event code tests
From: Athira Rajeev Add new folder for enabling perf event code tests which includes checking for group constraints, valid/invalid events, also checks for event excludes, alternatives so on. A new folder "event_code_tests", is created under "selftests/powerpc/pmu". Also updates the corresponding Makefiles in "selftests/powerpc" and "event_code_tests" folder. Signed-off-by: Athira Rajeev --- tools/testing/selftests/powerpc/pmu/Makefile | 11 +-- .../selftests/powerpc/pmu/event_code_tests/Makefile | 9 + 2 files changed, 18 insertions(+), 2 deletions(-) create mode 100644 tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile diff --git a/tools/testing/selftests/powerpc/pmu/Makefile b/tools/testing/selftests/powerpc/pmu/Makefile index edbd96d3b2ab..30803353bd7c 100644 --- a/tools/testing/selftests/powerpc/pmu/Makefile +++ b/tools/testing/selftests/powerpc/pmu/Makefile @@ -8,7 +8,7 @@ EXTRA_SOURCES := ../harness.c event.c lib.c ../utils.c top_srcdir = ../../../../.. include ../../lib.mk -all: $(TEST_GEN_PROGS) ebb sampling_tests +all: $(TEST_GEN_PROGS) ebb sampling_tests event_code_tests $(TEST_GEN_PROGS): $(EXTRA_SOURCES) @@ -27,6 +27,7 @@ override define RUN_TESTS $(DEFAULT_RUN_TESTS) TARGET=ebb; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET run_tests TARGET=sampling_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET run_tests + TARGET=event_code_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET run_tests endef DEFAULT_EMIT_TESTS := $(EMIT_TESTS) @@ -34,6 +35,7 @@ override define EMIT_TESTS $(DEFAULT_EMIT_TESTS) TARGET=ebb; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -s -C $$TARGET emit_tests TARGET=sampling_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -s -C $$TARGET emit_tests + TARGET=event_code_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -s -C $$TARGET emit_tests endef DEFAULT_INSTALL_RULE := $(INSTALL_RULE) @@ -41,12 +43,14 @@ override define INSTALL_RULE $(DEFAULT_INSTALL_RULE) TARGET=ebb; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET install TARGET=sampling_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET install + TARGET=event_code_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET install endef clean: $(RM) $(TEST_GEN_PROGS) $(OUTPUT)/loop.o TARGET=ebb; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET clean TARGET=sampling_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET clean + TARGET=event_code_tests; BUILD_TARGET=$$OUTPUT/$$TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET clean ebb: TARGET=$@; BUILD_TARGET=$$OUTPUT/$$TARGET; mkdir -p $$BUILD_TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -k -C $$TARGET all @@ -54,4 +58,7 @@ ebb: sampling_tests: TARGET=$@; BUILD_TARGET=$$OUTPUT/$$TARGET; mkdir -p $$BUILD_TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -k -C $$TARGET all -.PHONY: all run_tests clean ebb sampling_tests +event_code_tests: + TARGET=$@; BUILD_TARGET=$$OUTPUT/$$TARGET; mkdir -p $$BUILD_TARGET; $(MAKE) OUTPUT=$$BUILD_TARGET -k -C $$TARGET all + +.PHONY: all run_tests clean ebb sampling_tests event_code_tests diff --git a/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile b/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile new file mode 100644 index ..6377ae205064 --- /dev/null +++ b/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: GPL-2.0 +CFLAGS += -m64 + +TEST_GEN_PROGS := + +top_srcdir = ../../../../../.. +include ../../../lib.mk + +$(TEST_GEN_PROGS): ../../harness.c ../../utils.c ../event.c ../lib.c ../sampling_tests/misc.h ../sampling_tests/misc.c -- 2.31.1
[PATCH 05/35] selftest/powerpc/pmu: Add interface test for mmcra_ifm field of indirect call type
The testcase uses "instructions" event to check if the Instruction filtering mode(IFM) bits are programmed correctly for indirect branch type. Testcase checks if IFM bits are programmed correctly to Monitor Mode Control Register A (MMCRA) via perf interface for ISA v3.1 platform. Signed-off-by: Kajol Jain --- .../selftests/powerpc/pmu/branch_loops.S | 28 .../powerpc/pmu/sampling_tests/Makefile | 5 +- .../sampling_tests/mmcra_bhrb_ind_call_test.c | 69 +++ 3 files changed, 100 insertions(+), 2 deletions(-) create mode 100644 tools/testing/selftests/powerpc/pmu/branch_loops.S create mode 100644 tools/testing/selftests/powerpc/pmu/sampling_tests/mmcra_bhrb_ind_call_test.c Note: - branch_loops.S is derived from the branch_loop.S in the path: linux/tools/testing/selftests/powerpc/security/branch_loops.S diff --git a/tools/testing/selftests/powerpc/pmu/branch_loops.S b/tools/testing/selftests/powerpc/pmu/branch_loops.S new file mode 100644 index ..de758dd3cecf --- /dev/null +++ b/tools/testing/selftests/powerpc/pmu/branch_loops.S @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright 2022, Kajol Jain, IBM Corp. + */ + +#include + + .text + +#define ITER_SHIFT 31 + +FUNC_START(indirect_branch_loop) + li r3, 1 + sldir3, r3, ITER_SHIFT + +1: cmpdi r3, 0 + beqlr + + addir3, r3, -1 + + ld r4, 2f@got(%r2) + mtctr r4 + bctr + + .balign 32 +2: b 1b + +FUNC_END(indirect_branch_loop) diff --git a/tools/testing/selftests/powerpc/pmu/sampling_tests/Makefile b/tools/testing/selftests/powerpc/pmu/sampling_tests/Makefile index 6508e6074bac..89def6e706c8 100644 --- a/tools/testing/selftests/powerpc/pmu/sampling_tests/Makefile +++ b/tools/testing/selftests/powerpc/pmu/sampling_tests/Makefile @@ -4,9 +4,10 @@ CFLAGS += -m64 TEST_GEN_PROGS := mmcr0_exceptionbits_test mmcr0_cc56run_test mmcr0_pmccext_test \ mmcr0_pmcjce_test mmcr0_fc56_pmc1ce_test mmcr0_fc56_pmc56_test \ mmcr1_comb_test mmcr2_l2l3_test mmcr2_fcs_fch_test \ - mmcr3_src_test mmcra_thresh_marked_sample_test mmcra_thresh_cmp_test + mmcr3_src_test mmcra_thresh_marked_sample_test mmcra_thresh_cmp_test \ + mmcra_bhrb_ind_call_test top_srcdir = ../../../../../.. include ../../../lib.mk -$(TEST_GEN_PROGS): ../../harness.c ../../utils.c ../event.c ../lib.c misc.c misc.h ../loop.S +$(TEST_GEN_PROGS): ../../harness.c ../../utils.c ../event.c ../lib.c misc.c misc.h ../loop.S ../branch_loops.S diff --git a/tools/testing/selftests/powerpc/pmu/sampling_tests/mmcra_bhrb_ind_call_test.c b/tools/testing/selftests/powerpc/pmu/sampling_tests/mmcra_bhrb_ind_call_test.c new file mode 100644 index ..f0706730c099 --- /dev/null +++ b/tools/testing/selftests/powerpc/pmu/sampling_tests/mmcra_bhrb_ind_call_test.c @@ -0,0 +1,69 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright 2022, Kajol Jain, IBM Corp. + */ + +#include +#include + +#include "../event.h" +#include "misc.h" +#include "utils.h" + +extern void indirect_branch_loop(void); + +/* Instructions */ +#define EventCode 0x500fa + +/* ifm field for indirect branch mode */ +#define IFM_IND_BRANCH 0x2 + +/* + * A perf sampling test for mmcra + * field: ifm for bhrb ind_call. + */ +static int mmcra_bhrb_ind_call_test(void) +{ + struct event event; + u64 *intr_regs; + + /* +* Check for platform support for the test. +* This test is only aplicable on power10 +*/ + SKIP_IF(check_pvr_for_sampling_tests()); + SKIP_IF(!have_hwcap2(PPC_FEATURE2_ARCH_3_1)); + +/* Init the event for the sampling test */ + event_init_sampling(, EventCode); + event.attr.sample_regs_intr = platform_extended_mask; + event.attr.sample_type |= PERF_SAMPLE_BRANCH_STACK; + event.attr.branch_sample_type = PERF_SAMPLE_BRANCH_IND_CALL; + event.attr.exclude_kernel = 1; + + FAIL_IF(event_open()); + event.mmap_buffer = event_sample_buf_mmap(event.fd, 1); + + FAIL_IF(event_enable()); + + /* workload to make the event overflow */ + indirect_branch_loop(); + + FAIL_IF(event_disable()); + + intr_regs = get_intr_regs(, event.mmap_buffer); + + /* Check for intr_regs */ + FAIL_IF(!intr_regs); + + /* Verify that ifm bit is set properly in MMCRA */ + FAIL_IF(get_mmcra_ifm(get_reg_value(intr_regs, "MMCRA"), 5) != IFM_IND_BRANCH); + + event_close(); + return 0; +} + +int main(void) +{ + return test_harness(mmcra_bhrb_ind_call_test, "mmcra_bhrb_ind_call_test"); +} -- 2.31.1
[PATCH 35/35] selftest/powerpc/pmu: Add test for hardware cache events
The testcase checks if the transalation of a generic hardware cache event is done properly via perf interface. The hardware cache events has type as PERF_TYPE_HW_CACHE and each event points to raw event code id. Testcase checks different combination of cache level, cache event operation type and cache event result type and verify for a given event code, whether transalation matches with the current cache event mappings via perf interface. Signed-off-by: Kajol Jain --- .../powerpc/pmu/event_code_tests/Makefile | 3 +- .../hw_cache_event_type_test.c| 88 +++ 2 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/powerpc/pmu/event_code_tests/hw_cache_event_type_test.c diff --git a/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile b/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile index 755993d210f2..4e07d7046457 100644 --- a/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile +++ b/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile @@ -6,7 +6,8 @@ TEST_GEN_PROGS := group_constraint_pmc56_test group_pmc56_exclude_constraints_te group_constraint_mmcra_sample_test invalid_event_code_test reserved_bits_mmcra_thresh_ctl_test \ blacklisted_events_test event_alternatives_tests_p9 event_alternatives_tests_p10 generic_events_valid_test \ group_constraint_l2l3_sel_test group_constraint_cache_test group_constraint_thresh_cmp_test \ - group_constraint_unit_test group_constraint_thresh_ctl_test group_constraint_thresh_sel_test + group_constraint_unit_test group_constraint_thresh_ctl_test group_constraint_thresh_sel_test \ + hw_cache_event_type_test top_srcdir = ../../../../../.. include ../../../lib.mk diff --git a/tools/testing/selftests/powerpc/pmu/event_code_tests/hw_cache_event_type_test.c b/tools/testing/selftests/powerpc/pmu/event_code_tests/hw_cache_event_type_test.c new file mode 100644 index ..a45b1da5b568 --- /dev/null +++ b/tools/testing/selftests/powerpc/pmu/event_code_tests/hw_cache_event_type_test.c @@ -0,0 +1,88 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright 2022, Kajol Jain, IBM Corp. + */ + +#include +#include + +#include "../event.h" +#include "utils.h" +#include "../sampling_tests/misc.h" + +/* + * Load Missed L1, for power9 its pointing to PM_LD_MISS_L1_FIN (0x2c04e) and + * for power10 its pointing to PM_LD_MISS_L1 (0x3e054) + * + * Hardware cache level : PERF_COUNT_HW_CACHE_L1D + * Hardware cache event operation type : PERF_COUNT_HW_CACHE_OP_READ + * Hardware cache event result type : PERF_COUNT_HW_CACHE_RESULT_MISS + */ +#define EventCode_1 0x1 +/* + * Hardware cache level : PERF_COUNT_HW_CACHE_L1D + * Hardware cache event operation type : PERF_COUNT_HW_CACHE_OP_WRITE + * Hardware cache event result type : PERF_COUNT_HW_CACHE_RESULT_ACCESS + */ +#define EventCode_2 0x0100 +/* + * Hardware cache level : PERF_COUNT_HW_CACHE_DTLB + * Hardware cache event operation type : PERF_COUNT_HW_CACHE_OP_WRITE + * Hardware cache event result type : PERF_COUNT_HW_CACHE_RESULT_ACCESS + */ +#define EventCode_3 0x0103 +/* + * Hardware cache level : PERF_COUNT_HW_CACHE_L1D + * Hardware cache event operation type : PERF_COUNT_HW_CACHE_OP_READ + * Hardware cache event result type : Invalid ( > PERF_COUNT_HW_CACHE_RESULT_MAX) + */ +#define EventCode_4 0x03 + +/* + * A perf test to check valid hardware cache events. + */ +static int hw_cache_event_type_test(void) +{ + struct event event; + + /* Check for platform support for the test */ + SKIP_IF(platform_check_for_tests()); + + /* Skip for Generic compat PMU */ + SKIP_IF(check_for_generic_compat_pmu()); + + /* Init the event to test hardware cache event */ + event_init_opts(, EventCode_1, PERF_TYPE_HW_CACHE, "event"); + + /* Expected to success as its pointing to L1 load miss */ + FAIL_IF(event_open()); + event_close(); + + /* Init the event to test hardware cache event */ + event_init_opts(, EventCode_2, PERF_TYPE_HW_CACHE, "event"); + + /* Expected to fail as the corresponding cache event entry have 0 in that index */ + FAIL_IF(!event_open()); + event_close(); + + /* Init the event to test hardware cache event */ + event_init_opts(, EventCode_3, PERF_TYPE_HW_CACHE, "event"); + + /* Expected to fail as the corresponding cache event entry have -1 in that index */ + FAIL_IF(!event_open()); + event_close(); + + /* Init the event to test hardware cache event */ + event_init_opts(, EventCode_4, PERF_TYPE_HW_CACHE, "event"); + + /* Expected to fail as hardware cache event result type is Invalid */ + FAIL_IF(!event_open()); + event_close(); + + return 0; +} + +int main(void) +{ + return test_harness(hw_cache_event_type_test, "hw_cache_event_type_test"); +} -- 2.31.1
[PATCH 31/35] selftest/powerpc/pmu: Add selftest for group constraint check for MMCRA thresh_cmp field
Thresh compare bits for a event is used to program thresh compare field in Monitor Mode Control Register A (MMCRA: 9-18 bits for power9 and MMCRA: 8-18 bits for power10). When scheduling events as a group, all events in that group should match value in thresh compare bits. Otherwise event open for the sibling events will fail. Testcase uses event code "0x401e0" as leader and another event "0x101ec" as sibling event, and checks for thresh compare constraint via perf interface. Signed-off-by: Kajol Jain --- .../powerpc/pmu/event_code_tests/Makefile | 2 +- .../group_constraint_thresh_cmp_test.c| 96 +++ 2 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/powerpc/pmu/event_code_tests/group_constraint_thresh_cmp_test.c diff --git a/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile b/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile index dc27ca2ffcad..374044062561 100644 --- a/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile +++ b/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile @@ -5,7 +5,7 @@ TEST_GEN_PROGS := group_constraint_pmc56_test group_pmc56_exclude_constraints_te group_constraint_repeat_test group_constraint_radix_scope_qual_test reserved_bits_mmcra_sample_elig_mode_test \ group_constraint_mmcra_sample_test invalid_event_code_test reserved_bits_mmcra_thresh_ctl_test \ blacklisted_events_test event_alternatives_tests_p9 event_alternatives_tests_p10 generic_events_valid_test \ - group_constraint_l2l3_sel_test group_constraint_cache_test + group_constraint_l2l3_sel_test group_constraint_cache_test group_constraint_thresh_cmp_test top_srcdir = ../../../../../.. include ../../../lib.mk diff --git a/tools/testing/selftests/powerpc/pmu/event_code_tests/group_constraint_thresh_cmp_test.c b/tools/testing/selftests/powerpc/pmu/event_code_tests/group_constraint_thresh_cmp_test.c new file mode 100644 index ..9f1197104e8c --- /dev/null +++ b/tools/testing/selftests/powerpc/pmu/event_code_tests/group_constraint_thresh_cmp_test.c @@ -0,0 +1,96 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright 2022, Kajol Jain, IBM Corp. + */ + +#include +#include + +#include "../event.h" +#include "utils.h" +#include "../sampling_tests/misc.h" + +/* + * Primary PMU events used here is PM_MRK_INST_CMPL (0x401e0) and + * PM_THRESH_MET (0x101ec) + * Threshold event selection used is issue to complete for cycles + * Sampling criteria is Load or Store only sampling + */ +#define p9_EventCode_1 0x13e35340401e0 +#define p9_EventCode_2 0x17d34340101ec +#define p9_EventCode_3 0x13e35340101ec +#define p10_EventCode_1 0x35340401e0 +#define p10_EventCode_2 0x35340101ec + +/* + * Testcase for group constraint check of thresh_cmp bits which is + * used to program thresh compare field in Monitor Mode Control Register A + * (MMCRA: 9-18 bits for power9 and MMCRA: 8-18 bits for power10). + * All events in the group should match thresh compare bits otherwise + * event_open for the group will fail. + */ +static int group_constraint_thresh_cmp(void) +{ + struct event event, leader; + + /* Check for platform support for the test */ + SKIP_IF(platform_check_for_tests()); + + if (have_hwcap2(PPC_FEATURE2_ARCH_3_1)) { + /* Init the events for the group contraint check for thresh_cmp bits */ + event_init(, p10_EventCode_1); + + /* Add the thresh_cmp value for leader in config1 */ + leader.attr.config1 = 1000; + FAIL_IF(event_open()); + + event_init(, p10_EventCode_2); + + /* Add the different thresh_cmp value from the leader event in config1 */ + event.attr.config1 = 2000; + + /* Expected to fail as sibling and leader event request different thresh_cmp bits */ + FAIL_IF(!event_open_with_group(, leader.fd)); + + event_close(); + + /* Init the event for the group contraint thresh compare test */ + event_init(, p10_EventCode_2); + + /* Add the same thresh_cmp value for leader and sibling event in config1 */ + event.attr.config1 = 1000; + + /* Expected to succeed as sibling and leader event request same thresh_cmp bits */ + FAIL_IF(event_open_with_group(, leader.fd)); + + event_close(); + event_close(); + } else { + /* Init the events for the group contraint check for thresh_cmp bits */ + event_init(, p9_EventCode_1); + FAIL_IF(event_open()); + + event_init(, p9_EventCode_2); + + /* Expected to fail as sibling and leader event request different thresh_cmp bits */ + FAIL_IF(!event_open_with_group(, leader.fd)); + + event_close(); + + /* Init the event
[PATCH 34/35] selftest/powerpc/pmu: Add selftest for group constraint check for MMCRA thresh_sel field
Thresh select bits in the event code is used to program thresh_sel field in Monitor Mode Control Register A (MMCRA: 45-47). When scheduling events as a group, all events in that group should match value in these bits. Otherwise event open for the sibling events will fail. Testcase uses event code PM_MRK_INST_CMPL (0x401e0) as leader and another event PM_THRESH_MET (0x101ec) as sibling event, and checks if group constraint checks for thresh_sel field added correctly via perf interface. Signed-off-by: Kajol Jain --- .../powerpc/pmu/event_code_tests/Makefile | 2 +- .../group_constraint_thresh_sel_test.c| 63 +++ 2 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/powerpc/pmu/event_code_tests/group_constraint_thresh_sel_test.c diff --git a/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile b/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile index 16cbb2e52865..755993d210f2 100644 --- a/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile +++ b/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile @@ -6,7 +6,7 @@ TEST_GEN_PROGS := group_constraint_pmc56_test group_pmc56_exclude_constraints_te group_constraint_mmcra_sample_test invalid_event_code_test reserved_bits_mmcra_thresh_ctl_test \ blacklisted_events_test event_alternatives_tests_p9 event_alternatives_tests_p10 generic_events_valid_test \ group_constraint_l2l3_sel_test group_constraint_cache_test group_constraint_thresh_cmp_test \ - group_constraint_unit_test group_constraint_thresh_ctl_test + group_constraint_unit_test group_constraint_thresh_ctl_test group_constraint_thresh_sel_test top_srcdir = ../../../../../.. include ../../../lib.mk diff --git a/tools/testing/selftests/powerpc/pmu/event_code_tests/group_constraint_thresh_sel_test.c b/tools/testing/selftests/powerpc/pmu/event_code_tests/group_constraint_thresh_sel_test.c new file mode 100644 index ..50a8cd843ce7 --- /dev/null +++ b/tools/testing/selftests/powerpc/pmu/event_code_tests/group_constraint_thresh_sel_test.c @@ -0,0 +1,63 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright 2022, Kajol Jain, IBM Corp. + */ + +#include +#include + +#include "../event.h" +#include "utils.h" +#include "../sampling_tests/misc.h" + +/* + * Primary PMU events used here are PM_MRK_INST_CMPL (0x401e0) and + * PM_THRESH_MET (0x101ec). + * Threshold event selection used is issue to complete + * Sampling criteria is Load or Store only sampling + */ +#define EventCode_1 0x35340401e0 +#define EventCode_2 0x35540101ec +#define EventCode_3 0x35340101ec + +/* + * Testcase for group constraint check of thresh_sel bits which is + * used to program thresh select field in Monitor Mode Control Register A + * (MMCRA: 45-57). + * All events in the group should match thresh sel bits otherwise + * event_open for the group will fail. + */ +static int group_constraint_thresh_sel(void) +{ + struct event event, leader; + + /* Check for platform support for the test */ + SKIP_IF(platform_check_for_tests()); + + /* Init the events for the group contraint thresh select test */ + event_init(, EventCode_1); + FAIL_IF(event_open()); + + event_init(, EventCode_2); + + /* Expected to fail as sibling and leader event request different thresh_sel bits */ + FAIL_IF(!event_open_with_group(, leader.fd)); + + event_close(); + + /* Init the event for the group contraint thresh select test */ + event_init(, EventCode_3); + +/* Expected to succeed as sibling and leader event request same thresh_sel bits */ + FAIL_IF(event_open_with_group(, leader.fd)); + + event_close(); + event_close(); + + return 0; +} + +int main(void) +{ + return test_harness(group_constraint_thresh_sel, "group_constraint_thresh_sel"); +} -- 2.31.1
[PATCH 33/35] selftest/powerpc/pmu: Add selftest for group constraint check for MMCRA thresh_ctl field
Thresh control bits in the event code is used to program thresh_ctl field in Monitor Mode Control Register A (MMCRA: 48-55). When scheduling events as a group, all events in that group should match value in these bits. Otherwise event open for the sibling events will fail. Testcase uses event code PM_MRK_INST_CMPL (0x401e0) as leader and another event PM_THRESH_MET (101ec) as sibling event, and checks if group constraint checks for thresh_ctl field added correctly via perf interface. Signed-off-by: Kajol Jain --- .../powerpc/pmu/event_code_tests/Makefile | 2 +- .../group_constraint_thresh_ctl_test.c| 64 +++ 2 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/powerpc/pmu/event_code_tests/group_constraint_thresh_ctl_test.c diff --git a/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile b/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile index f72c73b5b79a..16cbb2e52865 100644 --- a/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile +++ b/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile @@ -6,7 +6,7 @@ TEST_GEN_PROGS := group_constraint_pmc56_test group_pmc56_exclude_constraints_te group_constraint_mmcra_sample_test invalid_event_code_test reserved_bits_mmcra_thresh_ctl_test \ blacklisted_events_test event_alternatives_tests_p9 event_alternatives_tests_p10 generic_events_valid_test \ group_constraint_l2l3_sel_test group_constraint_cache_test group_constraint_thresh_cmp_test \ - group_constraint_unit_test + group_constraint_unit_test group_constraint_thresh_ctl_test top_srcdir = ../../../../../.. include ../../../lib.mk diff --git a/tools/testing/selftests/powerpc/pmu/event_code_tests/group_constraint_thresh_ctl_test.c b/tools/testing/selftests/powerpc/pmu/event_code_tests/group_constraint_thresh_ctl_test.c new file mode 100644 index ..e0852ebc1671 --- /dev/null +++ b/tools/testing/selftests/powerpc/pmu/event_code_tests/group_constraint_thresh_ctl_test.c @@ -0,0 +1,64 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright 2022, Kajol Jain, IBM Corp. + */ + +#include +#include + +#include "../event.h" +#include "utils.h" +#include "../sampling_tests/misc.h" + +/* + * Primary PMU events used here are PM_MRK_INST_CMPL (0x401e0) and + * PM_THRESH_MET (0x101ec). + * Threshold event selection used is issue to complete and issue to + * finished for cycles + * Sampling criteria is Load or Store only sampling + */ +#define EventCode_1 0x35340401e0 +#define EventCode_2 0x34340101ec +#define EventCode_3 0x35340101ec + +/* + * Testcase for group constraint check of thresh_ctl bits which is + * used to program thresh compare field in Monitor Mode Control Register A + * (MMCR0: 48-55). + * All events in the group should match thresh ctl bits otherwise + * event_open for the group will fail. + */ +static int group_constraint_thresh_ctl(void) +{ + struct event event, leader; + + /* Check for platform support for the test */ + SKIP_IF(platform_check_for_tests()); + + /* Init the events for the group contraint thresh control test */ + event_init(, EventCode_1); + FAIL_IF(event_open()); + + event_init(, EventCode_2); + + /* Expected to fail as sibling and leader event request different thresh_ctl bits */ + FAIL_IF(!event_open_with_group(, leader.fd)); + + event_close(); + + /* Init the event for the group contraint thresh control test */ + event_init(, EventCode_3); + +/* Expected to succeed as sibling and leader event request same thresh_ctl bits */ + FAIL_IF(event_open_with_group(, leader.fd)); + + event_close(); + event_close(); + + return 0; +} + +int main(void) +{ + return test_harness(group_constraint_thresh_ctl, "group_constraint_thresh_ctl"); +} -- 2.31.1
[PATCH 21/35] selftest/powerpc/pmu: Add selftest for group constraint for MMCRA Sampling Mode field
From: Athira Rajeev Testcase for reserved bits in Monitor Mode Control Register A (MMCRA) Random Sampling Mode (SM) value. As per Instruction Set Architecture (ISA), the values 0x5, 0x9, 0xD, 0x19, 0x1D, 0x1A, 0x1E are reserved for sampling mode field. Test that having these reserved bit values should cause event_open to fail. Input event code in testcases uses these sampling bits along with 401e0 (PM_MRK_INST_CMPL). Signed-off-by: Athira Rajeev --- .../powerpc/pmu/event_code_tests/Makefile | 2 +- ...eserved_bits_mmcra_sample_elig_mode_test.c | 77 +++ 2 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/powerpc/pmu/event_code_tests/reserved_bits_mmcra_sample_elig_mode_test.c diff --git a/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile b/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile index 5b61fb0b9fd6..5dd482843572 100644 --- a/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile +++ b/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile @@ -2,7 +2,7 @@ CFLAGS += -m64 TEST_GEN_PROGS := group_constraint_pmc56_test group_pmc56_exclude_constraints_test group_constraint_pmc_count_test \ - group_constraint_repeat_test group_constraint_radix_scope_qual_test + group_constraint_repeat_test group_constraint_radix_scope_qual_test reserved_bits_mmcra_sample_elig_mode_test top_srcdir = ../../../../../.. include ../../../lib.mk diff --git a/tools/testing/selftests/powerpc/pmu/event_code_tests/reserved_bits_mmcra_sample_elig_mode_test.c b/tools/testing/selftests/powerpc/pmu/event_code_tests/reserved_bits_mmcra_sample_elig_mode_test.c new file mode 100644 index ..4c119c821b99 --- /dev/null +++ b/tools/testing/selftests/powerpc/pmu/event_code_tests/reserved_bits_mmcra_sample_elig_mode_test.c @@ -0,0 +1,77 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright 2022, Athira Rajeev, IBM Corp. + */ + +#include +#include "../event.h" +#include "../sampling_tests/misc.h" + +/* + * Testcase for reserved bits in Monitor Mode Control + * Register A (MMCRA) Random Sampling Mode (SM) value. + * As per Instruction Set Architecture (ISA), the values + * 0x5, 0x9, 0xD, 0x19, 0x1D, 0x1A, 0x1E are reserved + * for sampling mode field. Test that having these reserved + * bit values should cause event_open to fail. + * Input event code uses these sampling bits along with + * 401e0 (PM_MRK_INST_CMPL). + */ + +static int reserved_bits_mmcra_sample_elig_mode(void) +{ + struct event event; + + /* Check for platform support for the test */ + SKIP_IF(platform_check_for_tests()); + + /* Skip for Generic compat PMU */ + SKIP_IF(check_for_generic_compat_pmu()); + + /* +* MMCRA Random Sampling Mode (SM) values: 0x5 +* 0x9, 0xD, 0x19, 0x1D, 0x1A, 0x1E is reserved. +* Expected to fail when using these reserved values. +*/ + event_init(, 0x50401e0); + FAIL_IF(!event_open()); + + event_init(, 0x90401e0); + FAIL_IF(!event_open()); + + event_init(, 0xD0401e0); + FAIL_IF(!event_open()); + + event_init(, 0x190401e0); + FAIL_IF(!event_open()); + + event_init(, 0x1D0401e0); + FAIL_IF(!event_open()); + + event_init(, 0x1A0401e0); + FAIL_IF(!event_open()); + + event_init(, 0x1E0401e0); + FAIL_IF(!event_open()); + + /* +* MMCRA Random Sampling Mode (SM) value 0x10 +* is reserved in power10 and 0xC is reserved in +* power9. +*/ + if (PVR_VER(mfspr(SPRN_PVR)) == POWER10) { + event_init(, 0x100401e0); + FAIL_IF(!event_open()); + } else if (PVR_VER(mfspr(SPRN_PVR)) == POWER9) { + event_init(, 0xC0401e0); + FAIL_IF(!event_open()); + } + + return 0; +} + +int main(void) +{ + return test_harness(reserved_bits_mmcra_sample_elig_mode, + "reserved_bits_mmcra_sample_elig_mode"); +} -- 2.31.1
[PATCH 32/35] selftest/powerpc/pmu: Add selftest for group constraint for unit and pmc field in p9
Unit and pmu bits in the event code is used to program unit and pmc fields in Monitor Mode Control Register 1 (MMCR1). For power9 platform, incase unit field value is within 6 to 9, one of the event in the group should use PMC4. Otherwise event_open should fail for that group. Signed-off-by: Kajol Jain --- .../powerpc/pmu/event_code_tests/Makefile | 3 +- .../group_constraint_unit_test.c | 74 +++ 2 files changed, 76 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/powerpc/pmu/event_code_tests/group_constraint_unit_test.c diff --git a/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile b/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile index 374044062561..f72c73b5b79a 100644 --- a/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile +++ b/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile @@ -5,7 +5,8 @@ TEST_GEN_PROGS := group_constraint_pmc56_test group_pmc56_exclude_constraints_te group_constraint_repeat_test group_constraint_radix_scope_qual_test reserved_bits_mmcra_sample_elig_mode_test \ group_constraint_mmcra_sample_test invalid_event_code_test reserved_bits_mmcra_thresh_ctl_test \ blacklisted_events_test event_alternatives_tests_p9 event_alternatives_tests_p10 generic_events_valid_test \ - group_constraint_l2l3_sel_test group_constraint_cache_test group_constraint_thresh_cmp_test + group_constraint_l2l3_sel_test group_constraint_cache_test group_constraint_thresh_cmp_test \ + group_constraint_unit_test top_srcdir = ../../../../../.. include ../../../lib.mk diff --git a/tools/testing/selftests/powerpc/pmu/event_code_tests/group_constraint_unit_test.c b/tools/testing/selftests/powerpc/pmu/event_code_tests/group_constraint_unit_test.c new file mode 100644 index ..a2c18923dcec --- /dev/null +++ b/tools/testing/selftests/powerpc/pmu/event_code_tests/group_constraint_unit_test.c @@ -0,0 +1,74 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright 2022, Kajol Jain, IBM Corp. + */ + +#include +#include + +#include "../event.h" +#include "utils.h" +#include "../sampling_tests/misc.h" + +/* All successful D-side store dispatches for this thread with PMC 2 */ +#define EventCode_1 0x26080 +/* All successful D-side store dispatches for this thread with PMC 4 */ +#define EventCode_2 0x46080 +/* All successful D-side store dispatches for this thread that were L2 Miss with PMC 3 */ +#define EventCode_3 0x36880 + +/* + * Testcase for group constraint check of unit and pmc bits which is + * used to program corresponding unit and pmc field in Monitor Mode + * Control Register 1 (MMCR1) + * One of the event in the group should use PMC 4 incase units field + * value is within 6 to 9 otherwise event_open for the group will fail. + */ +static int group_constraint_unit(void) +{ + struct event *e, events[3]; + + /* +* Check for platform support for the test. +* Constraint to use PMC4 with one of the event in group, +* when the unit is within 6 to 9 is only applicable on +* power9. +*/ + SKIP_IF(platform_check_for_tests()); + SKIP_IF(have_hwcap2(PPC_FEATURE2_ARCH_3_1)); + + /* Init the events for the group contraint check for unit bits */ + e = [0]; + event_init(e, EventCode_1); + +/* Expected to fail as PMC 4 is not used with unit field value 6 to 9 */ + FAIL_IF(!event_open([0])); + + /* Init the events for the group contraint check for unit bits */ + e = [1]; + event_init(e, EventCode_2); + + /* Expected to pass as PMC 4 is used with unit field value 6 to 9 */ + FAIL_IF(event_open([1])); + + /* Init the event for the group contraint unit test */ + e = [2]; + event_init(e, EventCode_3); + + /* Expected to fail as PMC4 is not being used */ + FAIL_IF(!event_open_with_group([2], events[0].fd)); + + /* Expected to succeed as event using PMC4 */ + FAIL_IF(event_open_with_group([2], events[1].fd)); + + event_close([0]); + event_close([1]); + event_close([2]); + + return 0; +} + +int main(void) +{ + return test_harness(group_constraint_unit, "group_constraint_unit"); +} -- 2.31.1
[PATCH 30/35] selftest/powerpc/pmu: Add selftest for group constraint check for MMCR1 cache bits
Data and instruction cache qualifier bits in the event code is used to program cache select field in Monitor Mode Control Register 1 (MMCR1: 16-17). When scheduling events as a group, all events in that group should match value in these bits. Otherwise event open for the sibling events will fail. Testcase uses event code "0x1100fc" as leader and other events like "0x23e054" and "0x13e054" as sibling events to checks for l1 cache select field constraints via perf interface. Signed-off-by: Kajol Jain --- .../powerpc/pmu/event_code_tests/Makefile | 2 +- .../group_constraint_cache_test.c | 60 +++ 2 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/powerpc/pmu/event_code_tests/group_constraint_cache_test.c diff --git a/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile b/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile index 58e1a7a2ed4e..dc27ca2ffcad 100644 --- a/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile +++ b/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile @@ -5,7 +5,7 @@ TEST_GEN_PROGS := group_constraint_pmc56_test group_pmc56_exclude_constraints_te group_constraint_repeat_test group_constraint_radix_scope_qual_test reserved_bits_mmcra_sample_elig_mode_test \ group_constraint_mmcra_sample_test invalid_event_code_test reserved_bits_mmcra_thresh_ctl_test \ blacklisted_events_test event_alternatives_tests_p9 event_alternatives_tests_p10 generic_events_valid_test \ - group_constraint_l2l3_sel_test + group_constraint_l2l3_sel_test group_constraint_cache_test top_srcdir = ../../../../../.. include ../../../lib.mk diff --git a/tools/testing/selftests/powerpc/pmu/event_code_tests/group_constraint_cache_test.c b/tools/testing/selftests/powerpc/pmu/event_code_tests/group_constraint_cache_test.c new file mode 100644 index ..f4be05aa3a3d --- /dev/null +++ b/tools/testing/selftests/powerpc/pmu/event_code_tests/group_constraint_cache_test.c @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright 2022, Kajol Jain, IBM Corp. + */ + +#include +#include + +#include "../event.h" +#include "utils.h" +#include "../sampling_tests/misc.h" + +/* All L1 D cache load references counted at finish, gated by reject */ +#define EventCode_1 0x1100fc +/* Load Missed L1 */ +#define EventCode_2 0x23e054 +/* Load Missed L1 */ +#define EventCode_3 0x13e054 + +/* + * Testcase for group constraint check of data and instructions + * cache qualifier bits which is used to program cache select field in + * Monitor Mode Control Register 1 (MMCR1: 16-17) for l1 cache. + * All events in the group should match cache select bits otherwise + * event_open for the group will fail. + */ +static int group_constraint_cache(void) +{ + struct event event, leader; + + /* Check for platform support for the test */ + SKIP_IF(platform_check_for_tests()); + + /* Init the events for the group contraint check for l1 cache select bits */ + event_init(, EventCode_1); + FAIL_IF(event_open()); + + event_init(, EventCode_2); + + /* Expected to fail as sibling event doesn't request same l1 cache select bits as leader */ + FAIL_IF(!event_open_with_group(, leader.fd)); + + event_close(); + + /* Init the event for the group contraint l1 cache select test */ + event_init(, EventCode_3); + + /* Expected to succeed as sibling event request same l1 cache select bits as leader */ + FAIL_IF(event_open_with_group(, leader.fd)); + + event_close(); + event_close(); + + return 0; +} + +int main(void) +{ + return test_harness(group_constraint_cache, "group_constraint_cache"); +} -- 2.31.1
[PATCH 08/35] selftest/powerpc/pmu: Add interface test for bhrb disable field
The testcase uses "instructions" event to generate the samples and fetch Monitor Mode Control Register A (MMCRA) when overflow. Branch History Rolling Buffer(bhrb) disable bit is part of MMCRA which need to be verified by perf interface. Testcase checks if the bhrb disable bit of MMCRA register is programmed correctly via perf interface for ISA v3.1 platform Also make get_mmcra_ifm return type as u64. Signed-off-by: Kajol Jain --- .../powerpc/pmu/sampling_tests/Makefile | 3 +- .../powerpc/pmu/sampling_tests/misc.h | 2 +- .../sampling_tests/mmcra_bhrb_disable_test.c | 66 +++ 3 files changed, 69 insertions(+), 2 deletions(-) create mode 100644 tools/testing/selftests/powerpc/pmu/sampling_tests/mmcra_bhrb_disable_test.c diff --git a/tools/testing/selftests/powerpc/pmu/sampling_tests/Makefile b/tools/testing/selftests/powerpc/pmu/sampling_tests/Makefile index 53569fbb1cda..f4da49d55d57 100644 --- a/tools/testing/selftests/powerpc/pmu/sampling_tests/Makefile +++ b/tools/testing/selftests/powerpc/pmu/sampling_tests/Makefile @@ -5,7 +5,8 @@ TEST_GEN_PROGS := mmcr0_exceptionbits_test mmcr0_cc56run_test mmcr0_pmccext_test mmcr0_pmcjce_test mmcr0_fc56_pmc1ce_test mmcr0_fc56_pmc56_test \ mmcr1_comb_test mmcr2_l2l3_test mmcr2_fcs_fch_test \ mmcr3_src_test mmcra_thresh_marked_sample_test mmcra_thresh_cmp_test \ - mmcra_bhrb_ind_call_test mmcra_bhrb_any_test mmcra_bhrb_cond_test + mmcra_bhrb_ind_call_test mmcra_bhrb_any_test mmcra_bhrb_cond_test \ + mmcra_bhrb_disable_test top_srcdir = ../../../../../.. include ../../../lib.mk diff --git a/tools/testing/selftests/powerpc/pmu/sampling_tests/misc.h b/tools/testing/selftests/powerpc/pmu/sampling_tests/misc.h index c0e923f38793..874a1596add8 100644 --- a/tools/testing/selftests/powerpc/pmu/sampling_tests/misc.h +++ b/tools/testing/selftests/powerpc/pmu/sampling_tests/misc.h @@ -188,7 +188,7 @@ static inline int get_mmcra_sm(u64 mmcra, int pmc) return ((mmcra >> 42) & 0x3); } -static inline int get_mmcra_bhrb_disable(u64 mmcra, int pmc) +static inline u64 get_mmcra_bhrb_disable(u64 mmcra, int pmc) { if (pvr == POWER10) return mmcra & BHRB_DISABLE; diff --git a/tools/testing/selftests/powerpc/pmu/sampling_tests/mmcra_bhrb_disable_test.c b/tools/testing/selftests/powerpc/pmu/sampling_tests/mmcra_bhrb_disable_test.c new file mode 100644 index ..186a853c0f62 --- /dev/null +++ b/tools/testing/selftests/powerpc/pmu/sampling_tests/mmcra_bhrb_disable_test.c @@ -0,0 +1,66 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright 2022, Kajol Jain, IBM Corp. + */ + +#include +#include + +#include "../event.h" +#include "misc.h" +#include "utils.h" + +extern void thirty_two_instruction_loop(int loops); + +/* Instructions */ +#define EventCode 0x500fa + +/* + * A perf sampling test for mmcra + * field: bhrb_disable. + */ +static int mmcra_bhrb_disable_test(void) +{ + struct event event; + u64 *intr_regs; + + /* +* Check for platform support for the test. +* This test is only aplicable on power10 +*/ + SKIP_IF(check_pvr_for_sampling_tests()); + SKIP_IF(!have_hwcap2(PPC_FEATURE2_ARCH_3_1)); + +/* Init the event for the sampling test */ + event_init_sampling(, EventCode); + event.attr.sample_regs_intr = platform_extended_mask; + event.attr.sample_type |= PERF_SAMPLE_BRANCH_STACK; + event.attr.branch_sample_type = PERF_SAMPLE_BRANCH_ANY; + event.attr.exclude_kernel = 1; + + FAIL_IF(event_open()); + event.mmap_buffer = event_sample_buf_mmap(event.fd, 1); + + FAIL_IF(event_enable()); + + /* workload to make the event overflow */ + thirty_two_instruction_loop(1); + + FAIL_IF(event_disable()); + + intr_regs = get_intr_regs(, event.mmap_buffer); + + /* Check for intr_regs */ + FAIL_IF(!intr_regs); + + /* Verify that bhrb_disable bit is not set in MMCRA */ + FAIL_IF(get_mmcra_bhrb_disable(get_reg_value(intr_regs, "MMCRA"), 5)); + + event_close(); + return 0; +} + +int main(void) +{ + return test_harness(mmcra_bhrb_disable_test, "mmcra_bhrb_disable_test"); +} -- 2.31.1
[PATCH 29/35] selftest/powerpc/pmu: Add selftest for group constraint check for MMCR0 l2l3_sel bits
In power10, L2L3 select bits in the event code is used to program l2l3_sel field in Monitor Mode Control Register 0 (MMCR0: 56-60). When scheduling events as a group, all events in that group should match value in these bits. Otherwise event open for the sibling events will fail. Testcase uses event code "0x01046080" as leader and another events "0x26880" and "0x01026880" as sibling events, and checks for l2l3_sel constraints via perf interface for ISA v3.1 platform. Signed-off-by: Kajol Jain --- .../powerpc/pmu/event_code_tests/Makefile | 3 +- .../group_constraint_l2l3_sel_test.c | 64 +++ 2 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/powerpc/pmu/event_code_tests/group_constraint_l2l3_sel_test.c diff --git a/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile b/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile index 0d56f1ef530f..58e1a7a2ed4e 100644 --- a/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile +++ b/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile @@ -4,7 +4,8 @@ CFLAGS += -m64 TEST_GEN_PROGS := group_constraint_pmc56_test group_pmc56_exclude_constraints_test group_constraint_pmc_count_test \ group_constraint_repeat_test group_constraint_radix_scope_qual_test reserved_bits_mmcra_sample_elig_mode_test \ group_constraint_mmcra_sample_test invalid_event_code_test reserved_bits_mmcra_thresh_ctl_test \ - blacklisted_events_test event_alternatives_tests_p9 event_alternatives_tests_p10 generic_events_valid_test + blacklisted_events_test event_alternatives_tests_p9 event_alternatives_tests_p10 generic_events_valid_test \ + group_constraint_l2l3_sel_test top_srcdir = ../../../../../.. include ../../../lib.mk diff --git a/tools/testing/selftests/powerpc/pmu/event_code_tests/group_constraint_l2l3_sel_test.c b/tools/testing/selftests/powerpc/pmu/event_code_tests/group_constraint_l2l3_sel_test.c new file mode 100644 index ..85a636886069 --- /dev/null +++ b/tools/testing/selftests/powerpc/pmu/event_code_tests/group_constraint_l2l3_sel_test.c @@ -0,0 +1,64 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright 2022, Kajol Jain, IBM Corp. + */ + +#include +#include + +#include "../event.h" +#include "utils.h" +#include "../sampling_tests/misc.h" + +/* All successful D-side store dispatches for this thread */ +#define EventCode_1 0x01046080 +/* All successful D-side store dispatches for this thread that were L2 Miss */ +#define EventCode_2 0x26880 +/* All successful D-side store dispatches for this thread that were L2 Miss */ +#define EventCode_3 0x01026880 + +/* + * Testcase for group constraint check of l2l3_sel bits which is + * used to program l2l3 select field in Monitor Mode Control Register 0 + * (MMCR0: 56-60). + * All events in the group should match l2l3_sel bits otherwise + * event_open for the group should fail. + */ +static int group_constraint_l2l3_sel(void) +{ + struct event event, leader; + + /* +* Check for platform support for the test. +* This test is only aplicable on power10 +*/ + SKIP_IF(platform_check_for_tests()); + SKIP_IF(!have_hwcap2(PPC_FEATURE2_ARCH_3_1)); + + /* Init the events for the group contraint check for l2l3_sel bits */ + event_init(, EventCode_1); + FAIL_IF(event_open()); + + event_init(, EventCode_2); + + /* Expected to fail as sibling event doesn't request same l2l3_sel bits as leader */ + FAIL_IF(!event_open_with_group(, leader.fd)); + + event_close(); + + /* Init the event for the group contraint l2l3_sel test */ + event_init(, EventCode_3); + + /* Expected to succeed as sibling event request same l2l3_sel bits as leader */ + FAIL_IF(event_open_with_group(, leader.fd)); + + event_close(); + event_close(); + + return 0; +} + +int main(void) +{ + return test_harness(group_constraint_l2l3_sel, "group_constraint_l2l3_sel"); +} -- 2.31.1
[PATCH 28/35] selftest/powerpc/pmu: Add selftest for PERF_TYPE_HARDWARE events valid check
From: Athira Rajeev Testcase to ensure that using invalid event in generic event for PERF_TYPE_HARDWARE will fail. Invalid generic events in power10 are: - PERF_COUNT_HW_BUS_CYCLES - PERF_COUNT_HW_STALLED_CYCLES_FRONTEND - PERF_COUNT_HW_STALLED_CYCLES_BACKEND - PERF_COUNT_HW_REF_CPU_CYCLES Invalid generic events in power9 are: - PERF_COUNT_HW_BUS_CYCLES - PERF_COUNT_HW_REF_CPU_CYCLES Testcase does event open for valid and invalid generic events to ensure event open works for all valid events and fails for invalid events. Signed-off-by: Athira Rajeev --- .../powerpc/pmu/event_code_tests/Makefile | 2 +- .../generic_events_valid_test.c | 130 ++ 2 files changed, 131 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/powerpc/pmu/event_code_tests/generic_events_valid_test.c diff --git a/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile b/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile index 50bcc036dddf..0d56f1ef530f 100644 --- a/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile +++ b/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile @@ -4,7 +4,7 @@ CFLAGS += -m64 TEST_GEN_PROGS := group_constraint_pmc56_test group_pmc56_exclude_constraints_test group_constraint_pmc_count_test \ group_constraint_repeat_test group_constraint_radix_scope_qual_test reserved_bits_mmcra_sample_elig_mode_test \ group_constraint_mmcra_sample_test invalid_event_code_test reserved_bits_mmcra_thresh_ctl_test \ - blacklisted_events_test event_alternatives_tests_p9 event_alternatives_tests_p10 + blacklisted_events_test event_alternatives_tests_p9 event_alternatives_tests_p10 generic_events_valid_test top_srcdir = ../../../../../.. include ../../../lib.mk diff --git a/tools/testing/selftests/powerpc/pmu/event_code_tests/generic_events_valid_test.c b/tools/testing/selftests/powerpc/pmu/event_code_tests/generic_events_valid_test.c new file mode 100644 index ..0d237c15d3f2 --- /dev/null +++ b/tools/testing/selftests/powerpc/pmu/event_code_tests/generic_events_valid_test.c @@ -0,0 +1,130 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright 2022, Athira Rajeev, IBM Corp. + */ + +#include +#include +#include +#include "../event.h" +#include "../sampling_tests/misc.h" + +/* + * Testcase to ensure that using invalid event in generic + * event for PERF_TYPE_HARDWARE should fail + */ + +static int generic_events_valid_test(void) +{ + struct event event; + + /* Check for platform support for the test */ + SKIP_IF(platform_check_for_tests()); + + /* generic events is different in compat_mode */ + SKIP_IF(check_for_generic_compat_pmu()); + + /* +* Invalid generic events in power10: +* - PERF_COUNT_HW_BUS_CYCLES +* - PERF_COUNT_HW_STALLED_CYCLES_FRONTEND +* - PERF_COUNT_HW_STALLED_CYCLES_BACKEND +* - PERF_COUNT_HW_REF_CPU_CYCLES +*/ + if (PVR_VER(mfspr(SPRN_PVR)) == POWER10) { + event_init_opts(, PERF_COUNT_HW_CPU_CYCLES, PERF_TYPE_HARDWARE, "event"); + FAIL_IF(event_open()); + event_close(); + + event_init_opts(, PERF_COUNT_HW_INSTRUCTIONS, + PERF_TYPE_HARDWARE, "event"); + FAIL_IF(event_open()); + event_close(); + + event_init_opts(, PERF_COUNT_HW_CACHE_REFERENCES, + PERF_TYPE_HARDWARE, "event"); + FAIL_IF(event_open()); + event_close(); + + event_init_opts(, PERF_COUNT_HW_CACHE_MISSES, PERF_TYPE_HARDWARE, "event"); + FAIL_IF(event_open()); + event_close(); + + event_init_opts(, PERF_COUNT_HW_BRANCH_INSTRUCTIONS, + PERF_TYPE_HARDWARE, "event"); + FAIL_IF(event_open()); + event_close(); + + event_init_opts(, PERF_COUNT_HW_BRANCH_MISSES, PERF_TYPE_HARDWARE, "event"); + FAIL_IF(event_open()); + event_close(); + + event_init_opts(, PERF_COUNT_HW_BUS_CYCLES, PERF_TYPE_HARDWARE, "event"); + FAIL_IF(!event_open()); + + event_init_opts(, PERF_COUNT_HW_STALLED_CYCLES_FRONTEND, + PERF_TYPE_HARDWARE, "event"); + FAIL_IF(!event_open()); + + event_init_opts(, PERF_COUNT_HW_STALLED_CYCLES_BACKEND, + PERF_TYPE_HARDWARE, "event"); + FAIL_IF(!event_open()); + + event_init_opts(, PERF_COUNT_HW_REF_CPU_CYCLES, PERF_TYPE_HARDWARE, "event"); + FAIL_IF(!event_open()); + } else if (PVR_VER(mfspr(SPRN_PVR)) == POWER9) { + /* +* Invalid generic events in power9: +* - PERF_COUNT_HW_BUS_CYCLES +* - PERF_COUNT_HW_REF_CPU_CYCLES +
[PATCH 27/35] selftest/powerpc/pmu: Add selftest for event alternatives for power10
From: Athira Rajeev Platform specific PMU supports alternative event for some of the event codes. During perf_event_open, it any event group doesn't match constraint check criteria, further lookup is done to find alternative event. Code checks to see if it is possible to schedule event as group using alternative events. Testcase exercises the alternative event find code for power10. Example, Using PMC1 to PMC4 in a group and again trying to schedule PM_CYC_ALT (0x0001e) will fail since this exceeds number of programmable events in group. But since 0x600f4 is an alternative event for 0x0001e, it is possible to use 0x0001e in the group. Testcase uses such combination all events in power10 which has alternative event. Signed-off-by: Athira Rajeev --- .../powerpc/pmu/event_code_tests/Makefile | 2 +- .../event_alternatives_tests_p10.c| 109 ++ 2 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/powerpc/pmu/event_code_tests/event_alternatives_tests_p10.c diff --git a/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile b/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile index cf27e612290e..50bcc036dddf 100644 --- a/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile +++ b/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile @@ -4,7 +4,7 @@ CFLAGS += -m64 TEST_GEN_PROGS := group_constraint_pmc56_test group_pmc56_exclude_constraints_test group_constraint_pmc_count_test \ group_constraint_repeat_test group_constraint_radix_scope_qual_test reserved_bits_mmcra_sample_elig_mode_test \ group_constraint_mmcra_sample_test invalid_event_code_test reserved_bits_mmcra_thresh_ctl_test \ - blacklisted_events_test event_alternatives_tests_p9 + blacklisted_events_test event_alternatives_tests_p9 event_alternatives_tests_p10 top_srcdir = ../../../../../.. include ../../../lib.mk diff --git a/tools/testing/selftests/powerpc/pmu/event_code_tests/event_alternatives_tests_p10.c b/tools/testing/selftests/powerpc/pmu/event_code_tests/event_alternatives_tests_p10.c new file mode 100644 index ..8be7aada6523 --- /dev/null +++ b/tools/testing/selftests/powerpc/pmu/event_code_tests/event_alternatives_tests_p10.c @@ -0,0 +1,109 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright 2022, Athira Rajeev, IBM Corp. + */ + +#include +#include "../event.h" +#include "../sampling_tests/misc.h" + +#define PM_RUN_CYC_ALT 0x200f4 +#define PM_INST_DISP 0x200f2 +#define PM_BR_2PATH 0x20036 +#define PM_LD_MISS_L1 0x3e054 +#define PM_RUN_INST_CMPL_ALT 0x400fa + +#define EventCode_1 0x100fc +#define EventCode_2 0x200fa +#define EventCode_3 0x300fc +#define EventCode_4 0x400fc + +/* + * Check for event alternatives. + */ + +static int event_alternatives_tests_p10(void) +{ + struct event *e, events[5]; + int i; + + /* Check for platform support for the test */ + SKIP_IF(platform_check_for_tests()); + + /* +* PVR check is used here since PMU specific data like +* alternative events is handled by respective PMU driver +* code and using PVR will work correctly for all cases +* including generic compat mode. +*/ + SKIP_IF(PVR_VER(mfspr(SPRN_PVR)) != POWER10); + + SKIP_IF(check_for_generic_compat_pmu()); + + /* +* Test for event alternative for 0x0001e +* and 0x2. +*/ + e = [0]; + event_init(e, 0x0001e); + + e = [1]; + event_init(e, EventCode_1); + + e = [2]; + event_init(e, EventCode_2); + + e = [3]; + event_init(e, EventCode_3); + + e = [4]; + event_init(e, EventCode_4); + + FAIL_IF(event_open([0])); + + /* +* Expected to pass since 0x0001e has alternative event +* 0x600f4 in PMC6. So it can go in with other events +* in PMC1 to PMC4. +*/ + for (i = 1; i < 5; i++) + FAIL_IF(event_open_with_group([i], events[0].fd)); + + for (i = 0; i < 5; i++) + event_close([i]); + + e = [0]; + event_init(e, 0x2); + + e = [1]; + event_init(e, EventCode_1); + + e = [2]; + event_init(e, EventCode_2); + + e = [3]; + event_init(e, EventCode_3); + + e = [4]; + event_init(e, EventCode_4); + + FAIL_IF(event_open([0])); + + /* +* Expected to pass since 0x00020 has alternative event +* 0x500fa in PMC5. So it can go in with other events +* in PMC1 to PMC4. +*/ + for (i = 1; i < 5; i++) + FAIL_IF(event_open_with_group([i], events[0].fd)); + + for (i = 0; i < 5; i++) + event_close([i]); + + return 0; +} + +int main(void) +{ + return test_harness(event_alternatives_tests_p10, "event_alternatives_tests_p10"); +} -- 2.31.1
[PATCH 26/35] selftest/powerpc/pmu: Add selftest for event alternatives for power9
From: Athira Rajeev Platform specific PMU supports alternative event for some of the event codes. During perf_event_open, it any event group doesn't match constraint check criteria, further lookup is done to find alternative event. Code checks to see if it is possible to schedule event as group using alternative events. Testcase exercises the alternative event find code for power9. Example, since events in same PMC can't go in as a group, ideally using PM_RUN_CYC_ALT (0x200f4) and PM_BR_TAKEN_CMPL (0x200fa) will fail. But since RUN_CYC (0x600f4) is alternative event for 0x200f4, it is possible to use 0x600f4 and 0x200fa as group. Testcase uses such combination for all events in power9 which has an alternative event. Signed-off-by: Athira Rajeev --- .../powerpc/pmu/event_code_tests/Makefile | 2 +- .../event_alternatives_tests_p9.c | 116 ++ 2 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/powerpc/pmu/event_code_tests/event_alternatives_tests_p9.c diff --git a/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile b/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile index a5916a938154..cf27e612290e 100644 --- a/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile +++ b/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile @@ -4,7 +4,7 @@ CFLAGS += -m64 TEST_GEN_PROGS := group_constraint_pmc56_test group_pmc56_exclude_constraints_test group_constraint_pmc_count_test \ group_constraint_repeat_test group_constraint_radix_scope_qual_test reserved_bits_mmcra_sample_elig_mode_test \ group_constraint_mmcra_sample_test invalid_event_code_test reserved_bits_mmcra_thresh_ctl_test \ - blacklisted_events_test + blacklisted_events_test event_alternatives_tests_p9 top_srcdir = ../../../../../.. include ../../../lib.mk diff --git a/tools/testing/selftests/powerpc/pmu/event_code_tests/event_alternatives_tests_p9.c b/tools/testing/selftests/powerpc/pmu/event_code_tests/event_alternatives_tests_p9.c new file mode 100644 index ..f7dcf0e0447c --- /dev/null +++ b/tools/testing/selftests/powerpc/pmu/event_code_tests/event_alternatives_tests_p9.c @@ -0,0 +1,116 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright 2022, Athira Rajeev, IBM Corp. + */ + +#include +#include "../event.h" +#include "../sampling_tests/misc.h" + +#define PM_RUN_CYC_ALT 0x200f4 +#define PM_INST_DISP 0x200f2 +#define PM_BR_2PATH 0x20036 +#define PM_LD_MISS_L1 0x3e054 +#define PM_RUN_INST_CMPL_ALT 0x400fa + +#define EventCode_1 0x200fa +#define EventCode_2 0x200fc +#define EventCode_3 0x300fc +#define EventCode_4 0x400fc + +/* + * Check for event alternatives. + */ + +static int event_alternatives_tests_p9(void) +{ + struct event event, leader; + + /* Check for platform support for the test */ + SKIP_IF(platform_check_for_tests()); + + /* +* PVR check is used here since PMU specific data like +* alternative events is handled by respective PMU driver +* code and using PVR will work correctly for all cases +* including generic compat mode. +*/ + SKIP_IF(PVR_VER(mfspr(SPRN_PVR)) != POWER9); + + /* Skip for generic compat PMU */ + SKIP_IF(check_for_generic_compat_pmu()); + + /* Init the event for PM_RUN_CYC_ALT */ + event_init(, PM_RUN_CYC_ALT); + FAIL_IF(event_open()); + + event_init(, EventCode_1); + + /* +* Expected to pass since PM_RUN_CYC_ALT in PMC2 has alternative event +* 0x600f4. So it can go in with EventCode_1 which is using PMC2 +*/ + FAIL_IF(event_open_with_group(, leader.fd)); + + event_close(); + event_close(); + + event_init(, PM_INST_DISP); + FAIL_IF(event_open()); + + event_init(, EventCode_2); + /* +* Expected to pass since PM_INST_DISP in PMC2 has alternative event +* 0x300f2 in PMC3. So it can go in with EventCode_2 which is using PMC2 +*/ + FAIL_IF(event_open_with_group(, leader.fd)); + + event_close(); + event_close(); + + event_init(, PM_BR_2PATH); + FAIL_IF(event_open()); + + event_init(, EventCode_2); + /* +* Expected to pass since PM_BR_2PATH in PMC2 has alternative event +* 0x40036 in PMC4. So it can go in with EventCode_2 which is using PMC2 +*/ + FAIL_IF(event_open_with_group(, leader.fd)); + + event_close(); + event_close(); + + event_init(, PM_LD_MISS_L1); + FAIL_IF(event_open()); + + event_init(, EventCode_3); + /* +* Expected to pass since PM_LD_MISS_L1 in PMC3 has alternative event +* 0x400f0 in PMC4. So it can go in with EventCode_3 which is using PMC3 +*/ + FAIL_IF(event_open_with_group(, leader.fd)); + + event_close(); + event_close(); + + event_init(, PM_RUN_INST_CMPL_ALT); +
[PATCH 24/35] selftest/powerpc/pmu: Add selftest for reserved bit check for MMCRA thresh_ctl field
From: Athira Rajeev Testcase for reserved bits in Monitor Mode Control Register A (MMCRA) thresh_ctl bits. For MMCRA[48:51]/[52:55]) Threshold Start/Stop, 0b/0b is reserved. Signed-off-by: Athira Rajeev --- .../powerpc/pmu/event_code_tests/Makefile | 2 +- .../reserved_bits_mmcra_thresh_ctl_test.c | 44 +++ 2 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/powerpc/pmu/event_code_tests/reserved_bits_mmcra_thresh_ctl_test.c diff --git a/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile b/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile index 1ce1ef4586fd..e50570794337 100644 --- a/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile +++ b/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile @@ -3,7 +3,7 @@ CFLAGS += -m64 TEST_GEN_PROGS := group_constraint_pmc56_test group_pmc56_exclude_constraints_test group_constraint_pmc_count_test \ group_constraint_repeat_test group_constraint_radix_scope_qual_test reserved_bits_mmcra_sample_elig_mode_test \ - group_constraint_mmcra_sample_test invalid_event_code_test + group_constraint_mmcra_sample_test invalid_event_code_test reserved_bits_mmcra_thresh_ctl_test top_srcdir = ../../../../../.. include ../../../lib.mk diff --git a/tools/testing/selftests/powerpc/pmu/event_code_tests/reserved_bits_mmcra_thresh_ctl_test.c b/tools/testing/selftests/powerpc/pmu/event_code_tests/reserved_bits_mmcra_thresh_ctl_test.c new file mode 100644 index ..4ea1c2f8913f --- /dev/null +++ b/tools/testing/selftests/powerpc/pmu/event_code_tests/reserved_bits_mmcra_thresh_ctl_test.c @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright 2022, Athira Rajeev, IBM Corp. + */ + +#include +#include "../event.h" +#include "../sampling_tests/misc.h" + +/* + * Testcase for reserved bits in Monitor Mode + * Control Register A (MMCRA) thresh_ctl bits. + * For MMCRA[48:51]/[52:55]) Threshold Start/Stop, + * 0b/0b is reserved. + */ + +static int reserved_bits_mmcra_thresh_ctl(void) +{ + struct event event; + + /* Check for platform support for the test */ + SKIP_IF(platform_check_for_tests()); + + /* Skip for Generic compat PMU */ + SKIP_IF(check_for_generic_compat_pmu()); + + /* +* MMCRA[48:51]/[52:55]) Threshold Start/Stop +* events Selection. 0b/0b is reserved. +* Expected to fail when using these reserved values. +*/ + event_init(, 0xf0340401e0); + FAIL_IF(!event_open()); + + event_init(, 0x0f340401e0); + FAIL_IF(!event_open()); + + return 0; +} + +int main(void) +{ + return test_harness(reserved_bits_mmcra_thresh_ctl, "reserved_bits_mmcra_thresh_ctl"); +} -- 2.31.1
[PATCH 25/35] selftest/powerpc/pmu: Add selftest for blacklist events check in power9
From: Athira Rajeev Some of the events are blacklisted in power9. The list of blacklisted events are noted in power9-events-list.h When trying to do event open for any of these blacklisted event will cause a failure. Testcase ensures that using blacklisted events will cause event_open to fail in power9. This test is only applicable on power9 DD2.1 and DD2.2 and hence test adds checks to skip on other platforms. Signed-off-by: Athira Rajeev --- .../powerpc/pmu/event_code_tests/Makefile | 3 +- .../blacklisted_events_test.c | 132 ++ 2 files changed, 134 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/powerpc/pmu/event_code_tests/blacklisted_events_test.c diff --git a/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile b/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile index e50570794337..a5916a938154 100644 --- a/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile +++ b/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile @@ -3,7 +3,8 @@ CFLAGS += -m64 TEST_GEN_PROGS := group_constraint_pmc56_test group_pmc56_exclude_constraints_test group_constraint_pmc_count_test \ group_constraint_repeat_test group_constraint_radix_scope_qual_test reserved_bits_mmcra_sample_elig_mode_test \ - group_constraint_mmcra_sample_test invalid_event_code_test reserved_bits_mmcra_thresh_ctl_test + group_constraint_mmcra_sample_test invalid_event_code_test reserved_bits_mmcra_thresh_ctl_test \ + blacklisted_events_test top_srcdir = ../../../../../.. include ../../../lib.mk diff --git a/tools/testing/selftests/powerpc/pmu/event_code_tests/blacklisted_events_test.c b/tools/testing/selftests/powerpc/pmu/event_code_tests/blacklisted_events_test.c new file mode 100644 index ..fafeff19cb34 --- /dev/null +++ b/tools/testing/selftests/powerpc/pmu/event_code_tests/blacklisted_events_test.c @@ -0,0 +1,132 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright 2022, Athira Rajeev, IBM Corp. + */ + +#include +#include +#include +#include "../event.h" +#include "../sampling_tests/misc.h" + +#define PM_DTLB_MISS_16G 0x1c058 +#define PM_DERAT_MISS_2M 0x1c05a +#define PM_DTLB_MISS_2M 0x1c05c +#define PM_MRK_DTLB_MISS_1G 0x1d15c +#define PM_DTLB_MISS_4K 0x2c056 +#define PM_DERAT_MISS_1G 0x2c05a +#define PM_MRK_DERAT_MISS_2M 0x2d152 +#define PM_MRK_DTLB_MISS_4K 0x2d156 +#define PM_MRK_DTLB_MISS_16G 0x2d15e +#define PM_DTLB_MISS_64K 0x3c056 +#define PM_MRK_DERAT_MISS_1G 0x3d152 +#define PM_MRK_DTLB_MISS_64K 0x3d156 +#define PM_DISP_HELD_SYNC_HOLD 0x4003c +#define PM_DTLB_MISS_16M 0x4c056 +#define PM_DTLB_MISS_1G 0x4c05a +#define PM_MRK_DTLB_MISS_16M 0x4c15e +#define PM_MRK_ST_DONE_L2 0x10134 +#define PM_RADIX_PWC_L1_HIT 0x1f056 +#define PM_FLOP_CMPL 0x100f4 +#define PM_MRK_NTF_FIN 0x20112 +#define PM_RADIX_PWC_L2_HIT 0x2d024 +#define PM_IFETCH_THROTTLE 0x3405e +#define PM_MRK_L2_TM_ST_ABORT_SISTER 0x3e15c +#define PM_RADIX_PWC_L3_HIT 0x3f056 +#define PM_RUN_CYC_SMT2_MODE 0x3006c +#define PM_TM_TX_PASS_RUN_INST 0x4e014 + +#define PVR_POWER9_CUMULUS 0x2000 + +int blacklist_events_dd21[] = { + PM_MRK_ST_DONE_L2, + PM_RADIX_PWC_L1_HIT, + PM_FLOP_CMPL, + PM_MRK_NTF_FIN, + PM_RADIX_PWC_L2_HIT, + PM_IFETCH_THROTTLE, + PM_MRK_L2_TM_ST_ABORT_SISTER, + PM_RADIX_PWC_L3_HIT, + PM_RUN_CYC_SMT2_MODE, + PM_TM_TX_PASS_RUN_INST, + PM_DISP_HELD_SYNC_HOLD, +}; + +int blacklist_events_dd22[] = { + PM_DTLB_MISS_16G, + PM_DERAT_MISS_2M, + PM_DTLB_MISS_2M, + PM_MRK_DTLB_MISS_1G, + PM_DTLB_MISS_4K, + PM_DERAT_MISS_1G, + PM_MRK_DERAT_MISS_2M, + PM_MRK_DTLB_MISS_4K, + PM_MRK_DTLB_MISS_16G, + PM_DTLB_MISS_64K, + PM_MRK_DERAT_MISS_1G, + PM_MRK_DTLB_MISS_64K, + PM_DISP_HELD_SYNC_HOLD, + PM_DTLB_MISS_16M, + PM_DTLB_MISS_1G, + PM_MRK_DTLB_MISS_16M, +}; + +int pvr_min; + +/* + * check for power9 support for 2.1 and + * 2.2 model where blacklist is applicable. + */ +int check_for_power9_version(void) +{ + pvr_min = PVR_MIN(mfspr(SPRN_PVR)); + + SKIP_IF(PVR_VER(pvr) != POWER9); + SKIP_IF(!(pvr & PVR_POWER9_CUMULUS)); + + SKIP_IF(!(3 - pvr_min)); + + return 0; +} + +/* + * Testcase to ensure that using blacklisted bits in + * event code should cause event_open to fail in power9 + */ + +static int blacklisted_events(void) +{ + struct event event; + int i = 0; + + /* Check for platform support for the test */ + SKIP_IF(platform_check_for_tests()); + + /* +* check for power9 support for 2.1 and +* 2.2 model where blacklist is applicable. +*/ + SKIP_IF(check_for_power9_version()); + + /* Skip for Generic compat mode */ + SKIP_IF(check_for_generic_compat_pmu()); + + if (pvr_min == 1) { + for (i = 0; i <
[PATCH 23/35] selftest/powerpc/pmu: Add selftest for checking invalid bits in event code
From: Athira Rajeev Some of the bits in the event code is reserved for specific platforms. Event code bits 52-59 are reserved in power9, whereas in power10, these are used for programming Monitor Mode Control Register 3 (MMCR3). Bit 9 in event code is reserved in power9, whereas it is used for programming "radix_scope_qual" bit 18 in Monitor Mode Control Register 1 (MMCR1). Testcase to ensure that using reserved bits in event code should cause event_open to fail. Signed-off-by: Athira Rajeev --- .../powerpc/pmu/event_code_tests/Makefile | 2 +- .../invalid_event_code_test.c | 67 +++ 2 files changed, 68 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/powerpc/pmu/event_code_tests/invalid_event_code_test.c diff --git a/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile b/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile index 590b642ef900..1ce1ef4586fd 100644 --- a/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile +++ b/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile @@ -3,7 +3,7 @@ CFLAGS += -m64 TEST_GEN_PROGS := group_constraint_pmc56_test group_pmc56_exclude_constraints_test group_constraint_pmc_count_test \ group_constraint_repeat_test group_constraint_radix_scope_qual_test reserved_bits_mmcra_sample_elig_mode_test \ - group_constraint_mmcra_sample_test + group_constraint_mmcra_sample_test invalid_event_code_test top_srcdir = ../../../../../.. include ../../../lib.mk diff --git a/tools/testing/selftests/powerpc/pmu/event_code_tests/invalid_event_code_test.c b/tools/testing/selftests/powerpc/pmu/event_code_tests/invalid_event_code_test.c new file mode 100644 index ..f51fcab837fc --- /dev/null +++ b/tools/testing/selftests/powerpc/pmu/event_code_tests/invalid_event_code_test.c @@ -0,0 +1,67 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright 2022, Athira Rajeev, IBM Corp. + */ + +#include +#include +#include +#include "../event.h" +#include "../sampling_tests/misc.h" + +/* The data cache was reloaded from local core's L3 due to a demand load */ +#define EventCode_1 0x134001c040 +/* PM_DATA_RADIX_PROCESS_L2_PTE_FROM_L2 */ +#define EventCode_2 0x14242 +/* Event code with IFM, EBB, BHRB bits set in event code */ +#define EventCode_3 0xf01e + +/* + * Some of the bits in the event code is + * reserved for specific platforms. + * Event code bits 52-59 are reserved in power9, + * whereas in power10, these are used for programming + * Monitor Mode Control Register 3 (MMCR3). + * Bit 9 in event code is reserved in power9, + * whereas it is used for programming "radix_scope_qual" + * bit 18 in Monitor Mode Control Register 1 (MMCR1). + * + * Testcase to ensure that using reserved bits in + * event code should cause event_open to fail. + */ + +static int invalid_event_code(void) +{ + struct event event; + + /* Check for platform support for the test */ + SKIP_IF(platform_check_for_tests()); + + /* +* Events using MMCR3 bits and radix scope qual bits +* should fail in power9 and should succeed in power10. +* Init the events and check for pass/fail in event open. +*/ + if (have_hwcap2(PPC_FEATURE2_ARCH_3_1)) { + event_init(, EventCode_1); + FAIL_IF(event_open()); + event_close(); + + event_init(, EventCode_2); + FAIL_IF(event_open()); + event_close(); + } else { + event_init(, EventCode_1); + FAIL_IF(!event_open()); + + event_init(, EventCode_2); + FAIL_IF(!event_open()); + } + + return 0; +} + +int main(void) +{ + return test_harness(invalid_event_code, "invalid_event_code"); +} -- 2.31.1
[PATCH 22/35] selftest/powerpc/pmu: Add selftest for group constraint check MMCRA sample bits
From: Athira Rajeev Events with different "sample" field values which is used to program Monitor Mode Control Register A (MMCRA) in a group will fail to schedule. Testcase uses event with load only sampling mode as group leader and event with store only sampling as sibling event. So that it can check that using different sample bits in event code will fail in event open for group of events Signed-off-by: Athira Rajeev --- .../powerpc/pmu/event_code_tests/Makefile | 3 +- .../group_constraint_mmcra_sample_test.c | 54 +++ 2 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/powerpc/pmu/event_code_tests/group_constraint_mmcra_sample_test.c diff --git a/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile b/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile index 5dd482843572..590b642ef900 100644 --- a/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile +++ b/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile @@ -2,7 +2,8 @@ CFLAGS += -m64 TEST_GEN_PROGS := group_constraint_pmc56_test group_pmc56_exclude_constraints_test group_constraint_pmc_count_test \ - group_constraint_repeat_test group_constraint_radix_scope_qual_test reserved_bits_mmcra_sample_elig_mode_test + group_constraint_repeat_test group_constraint_radix_scope_qual_test reserved_bits_mmcra_sample_elig_mode_test \ + group_constraint_mmcra_sample_test top_srcdir = ../../../../../.. include ../../../lib.mk diff --git a/tools/testing/selftests/powerpc/pmu/event_code_tests/group_constraint_mmcra_sample_test.c b/tools/testing/selftests/powerpc/pmu/event_code_tests/group_constraint_mmcra_sample_test.c new file mode 100644 index ..ff625b5d80eb --- /dev/null +++ b/tools/testing/selftests/powerpc/pmu/event_code_tests/group_constraint_mmcra_sample_test.c @@ -0,0 +1,54 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright 2022, Athira Rajeev, IBM Corp. + */ + +#include +#include "../event.h" +#include "../sampling_tests/misc.h" + +#define EventCode_1 0x35340401e0 +#define EventCode_2 0x353c0101ec +#define EventCode_3 0x35340101ec +/* + * Test that using different sample bits in + * event code cause failure in schedule for + * group of events. + */ + +static int group_constraint_mmcra_sample(void) +{ + struct event event, leader; + + SKIP_IF(platform_check_for_tests()); + + /* +* Events with different "sample" field values +* in a group will fail to schedule. +* Use event with load only sampling mode as +* group leader. Use event with store only sampling +* as sibling event. +*/ + event_init(, EventCode_1); + FAIL_IF(event_open()); + + event_init(, EventCode_2); + + /* Expected to fail as sibling event doesn't use same sampling bits as leader */ + FAIL_IF(!event_open_with_group(, leader.fd)); + + event_init(, EventCode_3); + + /* Expected to pass as sibling event use same sampling bits as leader */ + FAIL_IF(event_open_with_group(, leader.fd)); + + event_close(); + event_close(); + + return 0; +} + +int main(void) +{ + return test_harness(group_constraint_mmcra_sample, "group_constraint_mmcra_sample"); +} -- 2.31.1
[PATCH 20/35] selftest/powerpc/pmu: Add selftest for group constraint check for radix_scope_qual field
From: Athira Rajeev Testcase for group constraint check for radix_scope_qual field which is used to program Monitor Mode Control Register (MMCR1) bit 18. All events in the group should match radix_scope_qual bit, otherwise event_open for the group should fail. Testcase uses "0x14242" (PM_DATA_RADIX_PROCESS_L2_PTE_FROM_L2) with radix_scope_qual bit set for power10. Signed-off-by: Athira Rajeev --- .../powerpc/pmu/event_code_tests/Makefile | 2 +- .../group_constraint_radix_scope_qual_test.c | 56 +++ 2 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/powerpc/pmu/event_code_tests/group_constraint_radix_scope_qual_test.c diff --git a/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile b/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile index ace100e3226e..5b61fb0b9fd6 100644 --- a/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile +++ b/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile @@ -2,7 +2,7 @@ CFLAGS += -m64 TEST_GEN_PROGS := group_constraint_pmc56_test group_pmc56_exclude_constraints_test group_constraint_pmc_count_test \ - group_constraint_repeat_test + group_constraint_repeat_test group_constraint_radix_scope_qual_test top_srcdir = ../../../../../.. include ../../../lib.mk diff --git a/tools/testing/selftests/powerpc/pmu/event_code_tests/group_constraint_radix_scope_qual_test.c b/tools/testing/selftests/powerpc/pmu/event_code_tests/group_constraint_radix_scope_qual_test.c new file mode 100644 index ..9225618b846a --- /dev/null +++ b/tools/testing/selftests/powerpc/pmu/event_code_tests/group_constraint_radix_scope_qual_test.c @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright 2022, Athira Rajeev, IBM Corp. + */ + +#include +#include "../event.h" +#include "../sampling_tests/misc.h" + +/* PM_DATA_RADIX_PROCESS_L2_PTE_FROM_L2 */ +#define EventCode_1 0x14242 +/* PM_DATA_RADIX_PROCESS_L2_PTE_FROM_L3 */ +#define EventCode_2 0x24242 + +/* + * Testcase for group constraint check for radix_scope_qual + * field which is used to program Monitor Mode Control + * egister (MMCR1) bit 18. + * All events in the group should match radix_scope_qual, + * bits otherwise event_open for the group should fail. + */ + +static int group_constraint_radix_scope_qual(void) +{ + struct event event, leader; + + /* +* Check for platform support for the test. +* This test is aplicable on power10 only. +*/ + SKIP_IF(platform_check_for_tests()); + SKIP_IF(!have_hwcap2(PPC_FEATURE2_ARCH_3_1)); + + /* Init the events for the group contraint check for radix_scope_qual bits */ + event_init(, EventCode_1); + FAIL_IF(event_open()); + + event_init(, 0x200fc); + + /* Expected to fail as sibling event doesn't request same radix_scope_qual bits as leader */ + FAIL_IF(!event_open_with_group(, leader.fd)); + + event_init(, EventCode_2); + /* Expected to pass as sibling event request same radix_scope_qual bits as leader */ + FAIL_IF(event_open_with_group(, leader.fd)); + + event_close(); + event_close(); + return 0; +} + +int main(void) +{ + return test_harness(group_constraint_radix_scope_qual, + "group_constraint_radix_scope_qual"); +} -- 2.31.1
[PATCH 19/35] selftest/powerpc/pmu: Add selftest for group constraint check when using same PMC
From: Athira Rajeev Testcase for group constraint check when using events with same PMC. Multiple events in a group asking for same PMC should fail. Testcase uses "0x22C040" on PMC2 as leader and also subling which is expected to fail. Using PMC1 for sibling event should pass the test. Signed-off-by: Athira Rajeev --- .../powerpc/pmu/event_code_tests/Makefile | 3 +- .../group_constraint_repeat_test.c| 56 +++ 2 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/powerpc/pmu/event_code_tests/group_constraint_repeat_test.c diff --git a/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile b/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile index 6310634c5beb..ace100e3226e 100644 --- a/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile +++ b/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile @@ -1,7 +1,8 @@ # SPDX-License-Identifier: GPL-2.0 CFLAGS += -m64 -TEST_GEN_PROGS := group_constraint_pmc56_test group_pmc56_exclude_constraints_test group_constraint_pmc_count_test +TEST_GEN_PROGS := group_constraint_pmc56_test group_pmc56_exclude_constraints_test group_constraint_pmc_count_test \ + group_constraint_repeat_test top_srcdir = ../../../../../.. include ../../../lib.mk diff --git a/tools/testing/selftests/powerpc/pmu/event_code_tests/group_constraint_repeat_test.c b/tools/testing/selftests/powerpc/pmu/event_code_tests/group_constraint_repeat_test.c new file mode 100644 index ..371cd05bb3ed --- /dev/null +++ b/tools/testing/selftests/powerpc/pmu/event_code_tests/group_constraint_repeat_test.c @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright 2022, Athira Rajeev, IBM Corp. + */ + +#include +#include "../event.h" +#include "../sampling_tests/misc.h" + +/* The processor's L1 data cache was reloaded */ +#define EventCode1 0x21C040 +#define EventCode2 0x22C040 + +/* + * Testcase for group constraint check + * when using events with same PMC. + * Multiple events in a group shouldn't + * ask for same PMC. If so it should fail. + */ + +static int group_constraint_repeat(void) +{ + struct event event, leader; + + /* Check for platform support for the test */ + SKIP_IF(platform_check_for_tests()); + + /* +* Two events in a group using same PMC +* should fail to get scheduled. Usei same PMC2 +* for leader and sibling event which is expected +* to fail. +*/ + event_init(, EventCode1); + FAIL_IF(event_open()); + + event_init(, EventCode1); + + /* Expected to fail since sibling event is requesting same PMC as leader */ + FAIL_IF(!event_open_with_group(, leader.fd)); + + event_init(, EventCode2); + + /* Expected to pass since sibling event is requesting different PMC */ + FAIL_IF(event_open_with_group(, leader.fd)); + + event_close(); + event_close(); + + return 0; +} + +int main(void) +{ + return test_harness(group_constraint_repeat, "group_constraint_repeat"); +} -- 2.31.1
[PATCH 18/35] selftest/powerpc/pmu: Add selftest to check constraint for number of counters in use.
From: Athira Rajeev Testcase for group constraint check for number of counters in use. The number of programmable counters is from PMC1 to PMC4. Testcase uses four events with PMC1 to PMC4 and 5th event without any PMC which is expected to fail since it is exceeding the number of counters in use. Signed-off-by: Athira Rajeev --- .../powerpc/pmu/event_code_tests/Makefile | 2 +- .../group_constraint_pmc_count_test.c | 70 +++ 2 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/powerpc/pmu/event_code_tests/group_constraint_pmc_count_test.c diff --git a/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile b/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile index c0eb28935e6e..6310634c5beb 100644 --- a/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile +++ b/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 CFLAGS += -m64 -TEST_GEN_PROGS := group_constraint_pmc56_test group_pmc56_exclude_constraints_test +TEST_GEN_PROGS := group_constraint_pmc56_test group_pmc56_exclude_constraints_test group_constraint_pmc_count_test top_srcdir = ../../../../../.. include ../../../lib.mk diff --git a/tools/testing/selftests/powerpc/pmu/event_code_tests/group_constraint_pmc_count_test.c b/tools/testing/selftests/powerpc/pmu/event_code_tests/group_constraint_pmc_count_test.c new file mode 100644 index ..af7c5c75101c --- /dev/null +++ b/tools/testing/selftests/powerpc/pmu/event_code_tests/group_constraint_pmc_count_test.c @@ -0,0 +1,70 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright 2022, Athira Rajeev, IBM Corp. + */ + +#include +#include "../event.h" +#include "../sampling_tests/misc.h" + +/* + * Testcase for number of counters in use. + * The number of programmable counters is from + * performance monitor counter 1 to performance + * monitor counter 4 (PMC1-PMC4). If number of + * counters in use exceeds the limit, next event + * should fail to schedule. + */ + +static int group_constraint_pmc_count(void) +{ + struct event *e, events[5]; + int i; + + /* Check for platform support for the test */ + SKIP_IF(platform_check_for_tests()); + + /* +* Test for number of counters in use. +* Use PMC1 to PMC4 for leader and 3 sibling +* events. Trying to open fourth event should +* fail here. +*/ + e = [0]; + event_init(e, 0x1001a); + + e = [1]; + event_init(e, 0x200fc); + + e = [2]; + event_init(e, 0x30080); + + e = [3]; + event_init(e, 0x40054); + + e = [4]; + event_init(e, 0x0002c); + + FAIL_IF(event_open([0])); + + /* +* The event_open will fail on event 4 if constraint +* check fails +*/ + for (i = 1; i < 5; i++) { + if (i == 4) + FAIL_IF(!event_open_with_group([i], events[0].fd)); + else + FAIL_IF(event_open_with_group([i], events[0].fd)); + } + + for (i = 1; i < 4; i++) + event_close([i]); + + return 0; +} + +int main(void) +{ + return test_harness(group_constraint_pmc_count, "group_constraint_pmc_count"); +} -- 2.31.1
[PATCH 17/35] selftest/powerpc/pmu: Add selftest to check PMC5/6 is excluded from some constraint checks
From: Athira Rajeev Events using Performance Monitor Counter 5 (PMC5) and Performance Monitor Counter 6 (PMC6) should be excluded from constraint check when scheduled along with group of events. Example, combination of PMC5, PMC6, and an event with cache bit will succeed to schedule though first two events doesn't have cache bit set. Testcase use three events, ie, 600f4(cycles), 500fa(instructions), 22C040 with cache bit (dc_ic) set to test this constraint check. Signed-off-by: Athira Rajeev --- .../powerpc/pmu/event_code_tests/Makefile | 2 +- .../group_pmc56_exclude_constraints_test.c| 64 +++ 2 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/powerpc/pmu/event_code_tests/group_pmc56_exclude_constraints_test.c diff --git a/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile b/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile index eb0017233b0b..c0eb28935e6e 100644 --- a/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile +++ b/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 CFLAGS += -m64 -TEST_GEN_PROGS := group_constraint_pmc56_test +TEST_GEN_PROGS := group_constraint_pmc56_test group_pmc56_exclude_constraints_test top_srcdir = ../../../../../.. include ../../../lib.mk diff --git a/tools/testing/selftests/powerpc/pmu/event_code_tests/group_pmc56_exclude_constraints_test.c b/tools/testing/selftests/powerpc/pmu/event_code_tests/group_pmc56_exclude_constraints_test.c new file mode 100644 index ..cff9ac170df6 --- /dev/null +++ b/tools/testing/selftests/powerpc/pmu/event_code_tests/group_pmc56_exclude_constraints_test.c @@ -0,0 +1,64 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright 2022, Athira Rajeev, IBM Corp. + */ + +#include +#include "../event.h" +#include +#include +#include "../sampling_tests/misc.h" + +/* + * Testcase for group constraint check for + * Performance Monitor Counter 5 (PMC5) and also + * Performance Monitor Counter 6 (PMC6). + * Test that pmc5/6 is excluded from constraint + * check when scheduled along with group of events. + */ + +static int group_pmc56_exclude_constraints(void) +{ + struct event *e, events[3]; + int i; + + /* Check for platform support for the test */ + SKIP_IF(platform_check_for_tests()); + + /* +* PMC5/6 is excluded from constraint bit +* check along with group of events. Use +* group of events with PMC5, PMC6 and also +* event with cache bit (dc_ic) set. Test expects +* this set of events to go in as a group. +*/ + e = [0]; + event_init(e, 0x500fa); + + e = [1]; + event_init(e, 0x600f4); + + e = [2]; + event_init(e, 0x22C040); + + FAIL_IF(event_open([0])); + + /* +* The event_open will fail if constraint check fails. +* Since we are asking for events in a group and since +* PMC5/PMC6 is excluded from group constraints, even_open +* should pass. +*/ + for (i = 1; i < 3; i++) + FAIL_IF(event_open_with_group([i], events[0].fd)); + + for (i = 0; i < 3; i++) + event_close([i]); + + return 0; +} + +int main(void) +{ + return test_harness(group_pmc56_exclude_constraints, "group_pmc56_exclude_constraints"); +} -- 2.31.1
[PATCH 16/35] selftest/powerpc/pmu: Add selftest for group constraint check for PMC5 and PMC6
From: Athira Rajeev Events using Performance Monitor Counter 5 (PMC5) and Performance Monitor Counter 6 (PMC6) can't have other fields in event code like cache bits, thresholding or marked bit. PMC5 and PMC6 only supports base events: ie 500fa and 600f4. Other combinations should fail. Testcase tries setting other bits in event code for 500fa and 600f4 to check this scenario. Signed-off-by: Athira Rajeev --- .../powerpc/pmu/event_code_tests/Makefile | 2 +- .../group_constraint_pmc56_test.c | 63 +++ 2 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/powerpc/pmu/event_code_tests/group_constraint_pmc56_test.c diff --git a/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile b/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile index 6377ae205064..eb0017233b0b 100644 --- a/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile +++ b/tools/testing/selftests/powerpc/pmu/event_code_tests/Makefile @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 CFLAGS += -m64 -TEST_GEN_PROGS := +TEST_GEN_PROGS := group_constraint_pmc56_test top_srcdir = ../../../../../.. include ../../../lib.mk diff --git a/tools/testing/selftests/powerpc/pmu/event_code_tests/group_constraint_pmc56_test.c b/tools/testing/selftests/powerpc/pmu/event_code_tests/group_constraint_pmc56_test.c new file mode 100644 index ..f5ee4796d46c --- /dev/null +++ b/tools/testing/selftests/powerpc/pmu/event_code_tests/group_constraint_pmc56_test.c @@ -0,0 +1,63 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright 2022, Athira Rajeev, IBM Corp. + */ + +#include +#include "../event.h" +#include "../sampling_tests/misc.h" + +/* + * Testcase for checking constraint checks for + * Performance Monitor Counter 5 (PMC5) and also + * Performance Monitor Counter 6 (PMC6). Events using + * PMC5/PMC6 shouldn't have other fields in event + * code like cache bits, thresholding or marked bit. + */ + +static int group_constraint_pmc56(void) +{ + struct event event; + + /* Check for platform support for the test */ + SKIP_IF(platform_check_for_tests()); + + /* +* Events using PMC5 and PMC6 with cache bit +* set in event code is expected to fail. +*/ + event_init(, 0x2500fa); + FAIL_IF(!event_open()); + + event_init(, 0x2600f4); + FAIL_IF(!event_open()); + + /* +* PMC5 and PMC6 only supports base events: +* ie 500fa and 600f4. Other combinations +* should fail. +*/ + event_init(, 0x501e0); + FAIL_IF(!event_open()); + + event_init(, 0x6001e); + FAIL_IF(!event_open()); + + event_init(, 0x501fa); + FAIL_IF(!event_open()); + + /* +* Events using PMC5 and PMC6 with random +* sampling bits set in event code should fail +* to schedule. +*/ + event_init(, 0x35340500fa); + FAIL_IF(!event_open()); + + return 0; +} + +int main(void) +{ + return test_harness(group_constraint_pmc56, "group_constraint_pmc56"); +} -- 2.31.1
[PATCH 14/35] selftest/powerpc/pmu: Add interface test for bhrb disable field for non-branch samples
The testcase uses "instructions" event to generate the samples and fetch Monitor Mode Control Register A (MMCRA) when overflow. Branch History Rolling Buffer(bhrb) disable bit is part of MMCRA which need to be verified by perf interface. Incase sample is not of branch type, bhrb disable bit is explicitly set to 1. Testcase checks if the bhrb disable bit is set of MMCRA register via perf interface for ISA v3.1 platform Signed-off-by: Kajol Jain --- .../powerpc/pmu/sampling_tests/Makefile | 2 +- .../mmcra_bhrb_disable_no_branch_test.c | 64 +++ 2 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/powerpc/pmu/sampling_tests/mmcra_bhrb_disable_no_branch_test.c diff --git a/tools/testing/selftests/powerpc/pmu/sampling_tests/Makefile b/tools/testing/selftests/powerpc/pmu/sampling_tests/Makefile index f966d3359c6b..9e67351fb252 100644 --- a/tools/testing/selftests/powerpc/pmu/sampling_tests/Makefile +++ b/tools/testing/selftests/powerpc/pmu/sampling_tests/Makefile @@ -7,7 +7,7 @@ TEST_GEN_PROGS := mmcr0_exceptionbits_test mmcr0_cc56run_test mmcr0_pmccext_test mmcr3_src_test mmcra_thresh_marked_sample_test mmcra_thresh_cmp_test \ mmcra_bhrb_ind_call_test mmcra_bhrb_any_test mmcra_bhrb_cond_test \ mmcra_bhrb_disable_test bhrb_no_crash_wo_pmu_test intr_regs_no_crash_wo_pmu_test \ - bhrb_filter_map_test mmcr1_sel_unit_cache_test + bhrb_filter_map_test mmcr1_sel_unit_cache_test mmcra_bhrb_disable_no_branch_test top_srcdir = ../../../../../.. include ../../../lib.mk diff --git a/tools/testing/selftests/powerpc/pmu/sampling_tests/mmcra_bhrb_disable_no_branch_test.c b/tools/testing/selftests/powerpc/pmu/sampling_tests/mmcra_bhrb_disable_no_branch_test.c new file mode 100644 index ..488c865387e4 --- /dev/null +++ b/tools/testing/selftests/powerpc/pmu/sampling_tests/mmcra_bhrb_disable_no_branch_test.c @@ -0,0 +1,64 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright 2022, Kajol Jain, IBM Corp. + */ + +#include +#include + +#include "../event.h" +#include "misc.h" +#include "utils.h" + +extern void thirty_two_instruction_loop(int loops); + +/* Instructions */ +#define EventCode 0x500fa + +/* + * A perf sampling test for mmcra + * field: bhrb_disable. + */ +static int mmcra_bhrb_disable_no_branch_test(void) +{ + struct event event; + u64 *intr_regs; + + /* +* Check for platform support for the test. +* This test is only aplicable on power10 +*/ + SKIP_IF(check_pvr_for_sampling_tests()); + SKIP_IF(!have_hwcap2(PPC_FEATURE2_ARCH_3_1)); + +/* Init the event for the sampling test */ + event_init_sampling(, EventCode); + event.attr.sample_regs_intr = platform_extended_mask; + event.attr.exclude_kernel = 1; + + FAIL_IF(event_open()); + event.mmap_buffer = event_sample_buf_mmap(event.fd, 1); + + FAIL_IF(event_enable()); + + /* workload to make the event overflow */ + thirty_two_instruction_loop(1); + + FAIL_IF(event_disable()); + + intr_regs = get_intr_regs(, event.mmap_buffer); + + /* Check for intr_regs */ + FAIL_IF(!intr_regs); + + /* Verify that bhrb_disable bit is set in MMCRA for non-branch samples */ + FAIL_IF(!get_mmcra_bhrb_disable(get_reg_value(intr_regs, "MMCRA"), 5)); + + event_close(); + return 0; +} + +int main(void) +{ + return test_harness(mmcra_bhrb_disable_no_branch_test, "mmcra_bhrb_disable_no_branch_test"); +} -- 2.31.1
[PATCH 13/35] selftest/powerpc/pmu: Add selftest for mmcr1 pmcxsel/unit/cache fields
From: Athira Rajeev The testcase uses event code "0x21c040" to verify the settings for different fields in Monitor Mode Control Register 1 (MMCR1). The fields include PMCxSEL, PMCXCOMB PMCxUNIT, cache. Checks if these fields are translated correctly via perf interface to MMCR1 Signed-off-by: Athira Rajeev --- .../powerpc/pmu/sampling_tests/Makefile | 2 +- .../mmcr1_sel_unit_cache_test.c | 77 +++ 2 files changed, 78 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/powerpc/pmu/sampling_tests/mmcr1_sel_unit_cache_test.c diff --git a/tools/testing/selftests/powerpc/pmu/sampling_tests/Makefile b/tools/testing/selftests/powerpc/pmu/sampling_tests/Makefile index ed9befc2f836..f966d3359c6b 100644 --- a/tools/testing/selftests/powerpc/pmu/sampling_tests/Makefile +++ b/tools/testing/selftests/powerpc/pmu/sampling_tests/Makefile @@ -7,7 +7,7 @@ TEST_GEN_PROGS := mmcr0_exceptionbits_test mmcr0_cc56run_test mmcr0_pmccext_test mmcr3_src_test mmcra_thresh_marked_sample_test mmcra_thresh_cmp_test \ mmcra_bhrb_ind_call_test mmcra_bhrb_any_test mmcra_bhrb_cond_test \ mmcra_bhrb_disable_test bhrb_no_crash_wo_pmu_test intr_regs_no_crash_wo_pmu_test \ - bhrb_filter_map_test + bhrb_filter_map_test mmcr1_sel_unit_cache_test top_srcdir = ../../../../../.. include ../../../lib.mk diff --git a/tools/testing/selftests/powerpc/pmu/sampling_tests/mmcr1_sel_unit_cache_test.c b/tools/testing/selftests/powerpc/pmu/sampling_tests/mmcr1_sel_unit_cache_test.c new file mode 100644 index ..f0c003282630 --- /dev/null +++ b/tools/testing/selftests/powerpc/pmu/sampling_tests/mmcr1_sel_unit_cache_test.c @@ -0,0 +1,77 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright 2022, Athira Rajeev, IBM Corp. + */ + +#include +#include + +#include "../event.h" +#include "misc.h" +#include "utils.h" + +#define MALLOC_SIZE (0x1 * 10) /* Ought to be enough .. */ + +/* The data cache was reloaded from local core's L3 due to a demand load */ +#define EventCode 0x21c040 + +/* + * A perf sampling test for mmcr1 + * fields : pmcxsel, unit, cache. + */ +static int mmcr1_sel_unit_cache(void) +{ + struct event event; + u64 *intr_regs; + char *p; + int i; + + /* Check for platform support for the test */ + SKIP_IF(check_pvr_for_sampling_tests()); + + p = malloc(MALLOC_SIZE); + FAIL_IF(!p); + + /* Init the event for the sampling test */ + event_init_sampling(, EventCode); + event.attr.sample_regs_intr = platform_extended_mask; + event.attr.sample_period = 1; + FAIL_IF(event_open()); + event.mmap_buffer = event_sample_buf_mmap(event.fd, 1); + + event_enable(); + + /* workload to make the event overflow */ + for (i = 0; i < MALLOC_SIZE; i += 0x1) + p[i] = i; + + event_disable(); + + /* Check for sample count */ + FAIL_IF(!collect_samples(event.mmap_buffer)); + + intr_regs = get_intr_regs(, event.mmap_buffer); + + /* Check for intr_regs */ + FAIL_IF(!intr_regs); + + /* +* Verify that pmcxsel, unit and cache field of MMCR1 +* match with corresponding event code fields +*/ + FAIL_IF(EV_CODE_EXTRACT(event.attr.config, pmcxsel) != + get_mmcr1_pmcxsel(get_reg_value(intr_regs, "MMCR1"), 1)); + FAIL_IF(EV_CODE_EXTRACT(event.attr.config, unit) != + get_mmcr1_unit(get_reg_value(intr_regs, "MMCR1"), 1)); + FAIL_IF(EV_CODE_EXTRACT(event.attr.config, cache) != + get_mmcr1_cache(get_reg_value(intr_regs, "MMCR1"), 1)); + + free(p); + event_close(); + return 0; +} + +int main(void) +{ + FAIL_IF(test_harness(mmcr1_sel_unit_cache, "mmcr1_sel_unit_cache")); +} -- 2.31.1
[PATCH 12/35] selftest/powerpc/pmu: Add selftest for checking valid and invalid bhrb filter maps
From: Athira Rajeev For PERF_SAMPLE_BRANCH_STACK sample type, different branch_sample_type, ie branch filters are supported. All the branch filters are not supported in powerpc. Example, power10 platform supports any, ind_call and cond branch filters. Whereas, it is different in power9. Testcase checks event open for invalid and valid branch sample types. The branch types for testcase are picked from "perf_branch_sample_type" in perf_event.h Signed-off-by: Athira Rajeev --- .../powerpc/pmu/sampling_tests/Makefile | 3 +- .../pmu/sampling_tests/bhrb_filter_map_test.c | 115 ++ 2 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/powerpc/pmu/sampling_tests/bhrb_filter_map_test.c diff --git a/tools/testing/selftests/powerpc/pmu/sampling_tests/Makefile b/tools/testing/selftests/powerpc/pmu/sampling_tests/Makefile index 8d4566dac440..ed9befc2f836 100644 --- a/tools/testing/selftests/powerpc/pmu/sampling_tests/Makefile +++ b/tools/testing/selftests/powerpc/pmu/sampling_tests/Makefile @@ -6,7 +6,8 @@ TEST_GEN_PROGS := mmcr0_exceptionbits_test mmcr0_cc56run_test mmcr0_pmccext_test mmcr1_comb_test mmcr2_l2l3_test mmcr2_fcs_fch_test \ mmcr3_src_test mmcra_thresh_marked_sample_test mmcra_thresh_cmp_test \ mmcra_bhrb_ind_call_test mmcra_bhrb_any_test mmcra_bhrb_cond_test \ - mmcra_bhrb_disable_test bhrb_no_crash_wo_pmu_test intr_regs_no_crash_wo_pmu_test + mmcra_bhrb_disable_test bhrb_no_crash_wo_pmu_test intr_regs_no_crash_wo_pmu_test \ + bhrb_filter_map_test top_srcdir = ../../../../../.. include ../../../lib.mk diff --git a/tools/testing/selftests/powerpc/pmu/sampling_tests/bhrb_filter_map_test.c b/tools/testing/selftests/powerpc/pmu/sampling_tests/bhrb_filter_map_test.c new file mode 100644 index ..8eee65504e22 --- /dev/null +++ b/tools/testing/selftests/powerpc/pmu/sampling_tests/bhrb_filter_map_test.c @@ -0,0 +1,115 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright 2022, Athira Rajeev, IBM Corp. + */ + +#include +#include + +#include "../event.h" +#include "misc.h" +#include "utils.h" + +/* + * A perf sampling test to check bhrb filter + * map. All the branch filters are not supported + * in powerpc. Supported filters in: + * power10: any, any_call, ind_call, cond + * power9: any, any_call + * + * Testcase checks event open for invalid bhrb filter + * types should fail and valid filter types should pass. + * Testcase does validity check for these branch + * sample types. + */ + +/* Invalid types for powerpc */ +int invalid_bhrb_filter_map[] = { + PERF_SAMPLE_BRANCH_USER, + PERF_SAMPLE_BRANCH_KERNEL, + PERF_SAMPLE_BRANCH_HV, + PERF_SAMPLE_BRANCH_ANY_RETURN, + PERF_SAMPLE_BRANCH_ABORT_TX, + PERF_SAMPLE_BRANCH_IN_TX, + PERF_SAMPLE_BRANCH_NO_TX, + PERF_SAMPLE_BRANCH_CALL_STACK, + PERF_SAMPLE_BRANCH_IND_JUMP, + PERF_SAMPLE_BRANCH_CALL, + PERF_SAMPLE_BRANCH_NO_FLAGS, + PERF_SAMPLE_BRANCH_NO_CYCLES, + PERF_SAMPLE_BRANCH_TYPE_SAVE, +}; + +/* Valid bhrb filters in power9/power10 */ +int bhrb_filter_map_valid_common[] = { + PERF_SAMPLE_BRANCH_ANY, + PERF_SAMPLE_BRANCH_ANY_CALL, +}; + +/* Valid bhrb filters in power10 */ +int bhrb_filter_map_valid_p10[] = { + PERF_SAMPLE_BRANCH_IND_CALL, + PERF_SAMPLE_BRANCH_COND, +}; + +static int bhrb_filter_map_test(void) +{ + struct event event; + int i; + + /* Check for platform support for the test */ + SKIP_IF(platform_check_for_tests()); + + /* +* Skip for Generic compat PMU since +* bhrb filters is not supported +*/ + SKIP_IF(check_for_generic_compat_pmu()); + + /* Init the event for the sampling test */ + event_init(, 0x1001e); + + event.attr.sample_period = 1000; + event.attr.sample_type = PERF_SAMPLE_BRANCH_STACK; + event.attr.disabled = 1; + + /* Invalid filter maps which are expected to fail in event_open */ + for (i = 0; i < ARRAY_SIZE(invalid_bhrb_filter_map); i++) { + event.attr.branch_sample_type = invalid_bhrb_filter_map[i]; + FAIL_IF(!event_open()); + } + + /* valid filter maps for power9/power10 which are expected to pass in event_open */ + for (i = 0; i < ARRAY_SIZE(bhrb_filter_map_valid_common); i++) { + event.attr.branch_sample_type = bhrb_filter_map_valid_common[i]; + FAIL_IF(event_open()); + event_close(); + } + + /* +* filter maps which are valid in power10 and invalid in power9. +* PVR check is used here since PMU specific data like bhrb filter +* alternative tests is handled by respective PMU driver code and +* using PVR will work correctly for all cases including generic +* compat mode. +*/ +
[PATCH 11/35] selftest/powerpc/pmu: Add selftest to check PERF_SAMPLE_REGS_INTR option will not crash on any platforms
From: Athira Rajeev With sampling, --intr-regs option is used for capturing interrupt regs. When --intr-regs option is used, PMU code uses is_sier_available() function which uses PMU flags in the code. In environment where platform specific PMU is not registered, PMU flags is not defined. A fix was added in kernel to address crash while accessing is_sier_available() function when pmu is not set. commit f75e7d73bdf7 ("powerpc/perf: Fix crash with is_sier_available when pmu is not set"). Add perf sampling test to exercise this code and make sure enabling intr_regs shouldn't crash in any platform. Testcase uses software event cycles since software event will work even in cases without PMU. Signed-off-by: Athira Rajeev --- .../powerpc/pmu/sampling_tests/Makefile | 2 +- .../intr_regs_no_crash_wo_pmu_test.c | 57 +++ 2 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/powerpc/pmu/sampling_tests/intr_regs_no_crash_wo_pmu_test.c diff --git a/tools/testing/selftests/powerpc/pmu/sampling_tests/Makefile b/tools/testing/selftests/powerpc/pmu/sampling_tests/Makefile index 8d4839cde013..8d4566dac440 100644 --- a/tools/testing/selftests/powerpc/pmu/sampling_tests/Makefile +++ b/tools/testing/selftests/powerpc/pmu/sampling_tests/Makefile @@ -6,7 +6,7 @@ TEST_GEN_PROGS := mmcr0_exceptionbits_test mmcr0_cc56run_test mmcr0_pmccext_test mmcr1_comb_test mmcr2_l2l3_test mmcr2_fcs_fch_test \ mmcr3_src_test mmcra_thresh_marked_sample_test mmcra_thresh_cmp_test \ mmcra_bhrb_ind_call_test mmcra_bhrb_any_test mmcra_bhrb_cond_test \ - mmcra_bhrb_disable_test bhrb_no_crash_wo_pmu_test + mmcra_bhrb_disable_test bhrb_no_crash_wo_pmu_test intr_regs_no_crash_wo_pmu_test top_srcdir = ../../../../../.. include ../../../lib.mk diff --git a/tools/testing/selftests/powerpc/pmu/sampling_tests/intr_regs_no_crash_wo_pmu_test.c b/tools/testing/selftests/powerpc/pmu/sampling_tests/intr_regs_no_crash_wo_pmu_test.c new file mode 100644 index ..839d2d225da0 --- /dev/null +++ b/tools/testing/selftests/powerpc/pmu/sampling_tests/intr_regs_no_crash_wo_pmu_test.c @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright 2022, Athira Rajeev, IBM Corp. + */ + +#include +#include + +#include "../event.h" +#include "misc.h" +#include "utils.h" + +/* + * A perf sampling test for making sure + * sampling with -intr-regs doesn't crash + * in any environment, say: + * - With generic compat PMU + * - without any PMU registered + * - With platform specific PMU. + * A fix for crash with intr_regs was + * addressed in commit: f75e7d73bdf7 in kernel. + * + * This testcase exercises this code path by doing + * intr_regs using software event. Software event is + * used since s/w event will work even in platform + * without PMU. + */ +static int intr_regs_no_crash_wo_pmu_test(void) +{ + struct event event; + + /* +* Init the event for the sampling test. +* This uses software event which works on +* any platform. +*/ + event_init_opts(, 0, PERF_TYPE_SOFTWARE, "cycles"); + + event.attr.sample_period = 1000; + event.attr.sample_type = PERF_SAMPLE_REGS_INTR; + event.attr.disabled = 1; + + /* +* Return code of event_open is not considered +* since test just expects no crash from using +* PERF_SAMPLE_REGS_INTR. +*/ + event_open(); + + event_close(); + return 0; +} + +int main(void) +{ + return test_harness(intr_regs_no_crash_wo_pmu_test, "intr_regs_no_crash_wo_pmu_test"); +} -- 2.31.1
[PATCH 10/35] selftest/powerpc/pmu: Add selftest to check branch stack enablement will not crash on any platforms
From: Athira Rajeev While enabling branch stack for an event, BHRB (Branch History Rolling Buffer) filter is set using bhrb_filter_map() callback. This callback is not defined for cases like generic_compat_pmu or in case where there is no PMU registered. A fix was added in kernel to address a crash issue observed while enabling branch stack for environments which doesn't have this callback. commit b460b512417a ("powerpc/perf: Fix crashes with generic_compat_pmu & BHRB"). Add perf sampling test to exercise this code path and make sure enabling branch stack shouldn't crash in any platform. Testcase uses software event cycles since software event is available and can be used even in cases without PMU. Signed-off-by: Athira Rajeev --- .../powerpc/pmu/sampling_tests/Makefile | 2 +- .../bhrb_no_crash_wo_pmu_test.c | 59 +++ 2 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/powerpc/pmu/sampling_tests/bhrb_no_crash_wo_pmu_test.c diff --git a/tools/testing/selftests/powerpc/pmu/sampling_tests/Makefile b/tools/testing/selftests/powerpc/pmu/sampling_tests/Makefile index f4da49d55d57..8d4839cde013 100644 --- a/tools/testing/selftests/powerpc/pmu/sampling_tests/Makefile +++ b/tools/testing/selftests/powerpc/pmu/sampling_tests/Makefile @@ -6,7 +6,7 @@ TEST_GEN_PROGS := mmcr0_exceptionbits_test mmcr0_cc56run_test mmcr0_pmccext_test mmcr1_comb_test mmcr2_l2l3_test mmcr2_fcs_fch_test \ mmcr3_src_test mmcra_thresh_marked_sample_test mmcra_thresh_cmp_test \ mmcra_bhrb_ind_call_test mmcra_bhrb_any_test mmcra_bhrb_cond_test \ - mmcra_bhrb_disable_test + mmcra_bhrb_disable_test bhrb_no_crash_wo_pmu_test top_srcdir = ../../../../../.. include ../../../lib.mk diff --git a/tools/testing/selftests/powerpc/pmu/sampling_tests/bhrb_no_crash_wo_pmu_test.c b/tools/testing/selftests/powerpc/pmu/sampling_tests/bhrb_no_crash_wo_pmu_test.c new file mode 100644 index ..4644c6782974 --- /dev/null +++ b/tools/testing/selftests/powerpc/pmu/sampling_tests/bhrb_no_crash_wo_pmu_test.c @@ -0,0 +1,59 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright 2022, Athira Rajeev, IBM Corp. + */ + +#include +#include + +#include "../event.h" +#include "misc.h" +#include "utils.h" + +/* + * A perf sampling test for making sure + * enabling branch stack doesn't crash in any + * environment, say: + * - With generic compat PMU + * - without any PMU registered + * - With platform specific PMU + * A fix for bhrb sampling crash was added in kernel + * via commit: b460b512417a ("powerpc/perf: Fix crashes + * with generic_compat_pmu & BHRB") + * + * This testcase exercises this code by doing branch + * stack enable for software event. s/w event is used + * since software event will work even in platform + * without PMU. + */ +static int bhrb_no_crash_wo_pmu_test(void) +{ + struct event event; + + /* +* Init the event for the sampling test. +* This uses software event which works on +* any platform. +*/ + event_init_opts(, 0, PERF_TYPE_SOFTWARE, "cycles"); + + event.attr.sample_period = 1000; + event.attr.sample_type = PERF_SAMPLE_BRANCH_STACK; + event.attr.disabled = 1; + + /* +* Return code of event_open is not +* considered since test just expects no crash from +* using PERF_SAMPLE_BRANCH_STACK. Also for environment +* like generic compat PMU, branch stack is unsupported. +*/ + event_open(); + + event_close(); + return 0; +} + +int main(void) +{ + return test_harness(bhrb_no_crash_wo_pmu_test, "bhrb_no_crash_wo_pmu_test"); +} -- 2.31.1
[PATCH 09/35] selftest/powerpc/pmu: Refactor the platform check and add macros to find array size/PVR
From: Athira Rajeev The platform check for selftest support "check_pvr_for_sampling_tests" is specific to sampling tests which includes PVR check, presence of PMU and extended regs support. Extended regs support is needed for sampling tests which tests whether PMU registers are programmed correctly. There could be other sampling tests which may not need extended regs, example, bhrb filter tests which only needs validity check via event open. Hence refactor the platform check to have a common function "platform_check_for_tests" that checks only for PVR check and presence of PMU. The existing function "check_pvr_for_sampling_tests" will invoke the common function and also will include checks for extended regs specific for sampling. The common function can also be used by tests other than sampling like event code tests. Add macro to find array size ("ARRAY_SIZE") to sampling tests "misc.h" file. This can be used in next tests to find event array size. Also update "include/reg.h" to add macros to find minor and major version from PVR which will be used in testcases. Signed-off-by: Athira Rajeev --- tools/testing/selftests/powerpc/include/reg.h | 4 .../powerpc/pmu/sampling_tests/misc.c | 20 +++ .../powerpc/pmu/sampling_tests/misc.h | 3 +++ 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/tools/testing/selftests/powerpc/include/reg.h b/tools/testing/selftests/powerpc/include/reg.h index c422be8a42b2..2ac7a4c7749c 100644 --- a/tools/testing/selftests/powerpc/include/reg.h +++ b/tools/testing/selftests/powerpc/include/reg.h @@ -55,6 +55,10 @@ #define PVR_VER(pvr) (((pvr) >> 16) & 0x) #define SPRN_PVR 0x11F +#define PVR_CFG(pvr)(((pvr) >> 8) & 0xF) /* Configuration field */ +#define PVR_MAJ(pvr)(((pvr) >> 4) & 0xF) /* Major revision field */ +#define PVR_MIN(pvr)(((pvr) >> 0) & 0xF) /* Minor revision field */ + #define SPRN_DSCR_PRIV 0x11/* Privilege State DSCR */ #define SPRN_DSCR 0x03/* Data Stream Control Register */ #define SPRN_PPR 896 /* Program Priority Register */ diff --git a/tools/testing/selftests/powerpc/pmu/sampling_tests/misc.c b/tools/testing/selftests/powerpc/pmu/sampling_tests/misc.c index 2562d8439d7d..facd6266b203 100644 --- a/tools/testing/selftests/powerpc/pmu/sampling_tests/misc.c +++ b/tools/testing/selftests/powerpc/pmu/sampling_tests/misc.c @@ -121,12 +121,10 @@ int check_extended_regs_support(void) return -1; } -int check_pvr_for_sampling_tests(void) +int platform_check_for_tests(void) { pvr = PVR_VER(mfspr(SPRN_PVR)); - platform_extended_mask = perf_get_platform_reg_mask(); - /* * Check for supported platforms * for sampling test @@ -138,19 +136,33 @@ int check_pvr_for_sampling_tests(void) * Check PMU driver registered by looking for * PPC_FEATURE2_EBB bit in AT_HWCAP2 */ - if (!have_hwcap2(PPC_FEATURE2_EBB)) + if (!have_hwcap2(PPC_FEATURE2_EBB) || !have_hwcap2(PPC_FEATURE2_ARCH_3_00)) goto out; + return 0; + +out: + printf("%s: Tests un-supported for this platform\n", __func__); + return -1; +} + +int check_pvr_for_sampling_tests(void) +{ + SKIP_IF(platform_check_for_tests()); + + platform_extended_mask = perf_get_platform_reg_mask(); /* check if platform supports extended regs */ if (check_extended_regs_support()) goto out; init_ev_encodes(); return 0; + out: printf("%s: Sampling tests un-supported\n", __func__); return -1; } + /* * Allocate mmap buffer of "mmap_pages" number of * pages. diff --git a/tools/testing/selftests/powerpc/pmu/sampling_tests/misc.h b/tools/testing/selftests/powerpc/pmu/sampling_tests/misc.h index 874a1596add8..4181755cf5a0 100644 --- a/tools/testing/selftests/powerpc/pmu/sampling_tests/misc.h +++ b/tools/testing/selftests/powerpc/pmu/sampling_tests/misc.h @@ -18,6 +18,8 @@ #define MMCR1_RSQ 0x2000ULL /* radix scope qual field */ #define BHRB_DISABLE0x20ULL /* MMCRA BHRB DISABLE bit */ +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) + extern int ev_mask_pmcxsel, ev_shift_pmcxsel; extern int ev_mask_marked, ev_shift_marked; extern int ev_mask_comb, ev_shift_comb; @@ -36,6 +38,7 @@ extern int ev_mask_mmcr3_src, ev_shift_mmcr3_src; extern int pvr; extern u64 platform_extended_mask; extern int check_pvr_for_sampling_tests(void); +extern int platform_check_for_tests(void); /* * Event code field extraction macro. -- 2.31.1
[PATCH 07/35] selftest/powerpc/pmu: Add interface test for mmcra_ifm field for conditional branch type
The testcase uses "instructions" event to check if the Instruction filtering mode(IFM) bits are programmed correctly for conditional branch type. Testcase checks if IFM bits is programmed correctly to Monitor Mode Control Register A (MMCRA) via perf interface for ISA v3.1 platform. Signed-off-by: Kajol Jain --- .../powerpc/pmu/sampling_tests/Makefile | 2 +- .../pmu/sampling_tests/mmcra_bhrb_cond_test.c | 69 +++ 2 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/powerpc/pmu/sampling_tests/mmcra_bhrb_cond_test.c diff --git a/tools/testing/selftests/powerpc/pmu/sampling_tests/Makefile b/tools/testing/selftests/powerpc/pmu/sampling_tests/Makefile index 63b084f66dbf..53569fbb1cda 100644 --- a/tools/testing/selftests/powerpc/pmu/sampling_tests/Makefile +++ b/tools/testing/selftests/powerpc/pmu/sampling_tests/Makefile @@ -5,7 +5,7 @@ TEST_GEN_PROGS := mmcr0_exceptionbits_test mmcr0_cc56run_test mmcr0_pmccext_test mmcr0_pmcjce_test mmcr0_fc56_pmc1ce_test mmcr0_fc56_pmc56_test \ mmcr1_comb_test mmcr2_l2l3_test mmcr2_fcs_fch_test \ mmcr3_src_test mmcra_thresh_marked_sample_test mmcra_thresh_cmp_test \ - mmcra_bhrb_ind_call_test mmcra_bhrb_any_test + mmcra_bhrb_ind_call_test mmcra_bhrb_any_test mmcra_bhrb_cond_test top_srcdir = ../../../../../.. include ../../../lib.mk diff --git a/tools/testing/selftests/powerpc/pmu/sampling_tests/mmcra_bhrb_cond_test.c b/tools/testing/selftests/powerpc/pmu/sampling_tests/mmcra_bhrb_cond_test.c new file mode 100644 index ..3e08176eb7f8 --- /dev/null +++ b/tools/testing/selftests/powerpc/pmu/sampling_tests/mmcra_bhrb_cond_test.c @@ -0,0 +1,69 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright 2022, Kajol Jain, IBM Corp. + */ + +#include +#include + +#include "../event.h" +#include "misc.h" +#include "utils.h" + +extern void thirty_two_instruction_loop(int loops); + +/* Instructions */ +#define EventCode 0x500fa + +/* ifm field for conditional branch mode */ +#define IFM_COND_BRANCH 0x3 + +/* + * A perf sampling test for mmcra + * field: ifm for bhrb cond call. + */ +static int mmcra_bhrb_cond_test(void) +{ + struct event event; + u64 *intr_regs; + + /* +* Check for platform support for the test. +* This test is only aplicable on power10 +*/ + SKIP_IF(check_pvr_for_sampling_tests()); + SKIP_IF(!have_hwcap2(PPC_FEATURE2_ARCH_3_1)); + +/* Init the event for the sampling test */ + event_init_sampling(, EventCode); + event.attr.sample_regs_intr = platform_extended_mask; + event.attr.sample_type |= PERF_SAMPLE_BRANCH_STACK; + event.attr.branch_sample_type = PERF_SAMPLE_BRANCH_COND; + event.attr.exclude_kernel = 1; + + FAIL_IF(event_open()); + event.mmap_buffer = event_sample_buf_mmap(event.fd, 1); + + FAIL_IF(event_enable()); + + /* workload to make the event overflow */ + thirty_two_instruction_loop(1); + + FAIL_IF(event_disable()); + + intr_regs = get_intr_regs(, event.mmap_buffer); + + /* Check for intr_regs */ + FAIL_IF(!intr_regs); + + /* Verify that ifm bit is set properly in MMCRA */ + FAIL_IF(get_mmcra_ifm(get_reg_value(intr_regs, "MMCRA"), 5) != IFM_COND_BRANCH); + + event_close(); + return 0; +} + +int main(void) +{ + return test_harness(mmcra_bhrb_cond_test, "mmcra_bhrb_cond_test"); +} -- 2.31.1
[PATCH 06/35] selftest/powerpc/pmu: Add interface test for mmcra_ifm field for any branch type
The testcase uses "instructions" event to check if the Instruction filtering mode(IFM) bits are programmed correctly for type any branch. Testcase checks if IFM bits is programmed correctly to Monitor Mode Control Register A (MMCRA) via perf interface. Signed-off-by: Kajol Jain --- .../powerpc/pmu/sampling_tests/Makefile | 2 +- .../pmu/sampling_tests/mmcra_bhrb_any_test.c | 65 +++ 2 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/powerpc/pmu/sampling_tests/mmcra_bhrb_any_test.c diff --git a/tools/testing/selftests/powerpc/pmu/sampling_tests/Makefile b/tools/testing/selftests/powerpc/pmu/sampling_tests/Makefile index 89def6e706c8..63b084f66dbf 100644 --- a/tools/testing/selftests/powerpc/pmu/sampling_tests/Makefile +++ b/tools/testing/selftests/powerpc/pmu/sampling_tests/Makefile @@ -5,7 +5,7 @@ TEST_GEN_PROGS := mmcr0_exceptionbits_test mmcr0_cc56run_test mmcr0_pmccext_test mmcr0_pmcjce_test mmcr0_fc56_pmc1ce_test mmcr0_fc56_pmc56_test \ mmcr1_comb_test mmcr2_l2l3_test mmcr2_fcs_fch_test \ mmcr3_src_test mmcra_thresh_marked_sample_test mmcra_thresh_cmp_test \ - mmcra_bhrb_ind_call_test + mmcra_bhrb_ind_call_test mmcra_bhrb_any_test top_srcdir = ../../../../../.. include ../../../lib.mk diff --git a/tools/testing/selftests/powerpc/pmu/sampling_tests/mmcra_bhrb_any_test.c b/tools/testing/selftests/powerpc/pmu/sampling_tests/mmcra_bhrb_any_test.c new file mode 100644 index ..14854694af62 --- /dev/null +++ b/tools/testing/selftests/powerpc/pmu/sampling_tests/mmcra_bhrb_any_test.c @@ -0,0 +1,65 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright 2022, Kajol Jain, IBM Corp. + */ + +#include +#include + +#include "../event.h" +#include "misc.h" +#include "utils.h" + +extern void thirty_two_instruction_loop(int loops); + +/* Instructions */ +#define EventCode 0x500fa + +/* ifm field for any branch mode */ +#define IFM_ANY_BRANCH 0x0 + +/* + * A perf sampling test for mmcra + * field: ifm for bhrb any call. + */ +static int mmcra_bhrb_any_test(void) +{ + struct event event; + u64 *intr_regs; + + /* Check for platform support for the test */ + SKIP_IF(check_pvr_for_sampling_tests()); + +/* Init the event for the sampling test */ + event_init_sampling(, EventCode); + event.attr.sample_regs_intr = platform_extended_mask; + event.attr.sample_type |= PERF_SAMPLE_BRANCH_STACK; + event.attr.branch_sample_type = PERF_SAMPLE_BRANCH_ANY; + event.attr.exclude_kernel = 1; + + FAIL_IF(event_open()); + event.mmap_buffer = event_sample_buf_mmap(event.fd, 1); + + FAIL_IF(event_enable()); + + /* workload to make the event overflow */ + thirty_two_instruction_loop(1); + + FAIL_IF(event_disable()); + + intr_regs = get_intr_regs(, event.mmap_buffer); + + /* Check for intr_regs */ + FAIL_IF(!intr_regs); + + /* Verify that ifm bit is set properly in MMCRA */ + FAIL_IF(get_mmcra_ifm(get_reg_value(intr_regs, "MMCRA"), 5) != IFM_ANY_BRANCH); + + event_close(); + return 0; +} + +int main(void) +{ + return test_harness(mmcra_bhrb_any_test, "mmcra_bhrb_any_test"); +} -- 2.31.1
[PATCH 04/35] selftest/powerpc/pmu: Add support for branch sampling in get_intr_regs function
Add support for sample type as PERF_SAMPLE_BRANCH_STACK in sampling tests. This change is a precursor/helper for sampling testcases, that test branck stack feature in perf interface. Signed-off-by: Kajol Jain --- .../powerpc/pmu/sampling_tests/misc.c | 21 ++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/powerpc/pmu/sampling_tests/misc.c b/tools/testing/selftests/powerpc/pmu/sampling_tests/misc.c index eff56aa9f511..2562d8439d7d 100644 --- a/tools/testing/selftests/powerpc/pmu/sampling_tests/misc.c +++ b/tools/testing/selftests/powerpc/pmu/sampling_tests/misc.c @@ -259,13 +259,32 @@ u64 *get_intr_regs(struct event *event, void *sample_buff) u64 *intr_regs; size_t size = 0; - if ((type ^ PERF_SAMPLE_REGS_INTR)) + if ((type ^ (PERF_SAMPLE_REGS_INTR | PERF_SAMPLE_BRANCH_STACK)) && + (type ^ PERF_SAMPLE_REGS_INTR)) return NULL; intr_regs = (u64 *)perf_read_first_sample(sample_buff, ); if (!intr_regs) return NULL; + if (type & PERF_SAMPLE_BRANCH_STACK) { + /* +* PERF_RECORD_SAMPLE and PERF_SAMPLE_BRANCH_STACK: +* struct { +* struct perf_event_header hdr; +* u64 number_of_branches; +* struct perf_branch_entry[number_of_branches]; +* u64 data[]; +* }; +* struct perf_branch_entry { +* u64 from; +* u64 to; +* u64 misc; +* }; +*/ + intr_regs += ((*intr_regs) * 3) + 1; + } + /* * First entry in the sample buffer used to specify * PERF_SAMPLE_REGS_ABI_64, skip perf regs abi to access -- 2.31.1
[PATCH 03/35] selftest/powerpc/pmu: Add interface test for mmcra_thresh_cmp fields
The testcase uses event code 0x35340401e0 for load only sampling, to verify the settings of thresh compare field in Monitor Mode Control Register A (MMCRA: 9-18 bits for power9 and MMCRA: 8-18 bits for power10). Testcase checks if the thresh compare field is programmed correctly via perf interface to MMCRA register. Signed-off-by: Kajol Jain --- .../powerpc/pmu/sampling_tests/Makefile | 2 +- .../sampling_tests/mmcra_thresh_cmp_test.c| 74 +++ 2 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 tools/testing/selftests/powerpc/pmu/sampling_tests/mmcra_thresh_cmp_test.c diff --git a/tools/testing/selftests/powerpc/pmu/sampling_tests/Makefile b/tools/testing/selftests/powerpc/pmu/sampling_tests/Makefile index a785c6a173b9..6508e6074bac 100644 --- a/tools/testing/selftests/powerpc/pmu/sampling_tests/Makefile +++ b/tools/testing/selftests/powerpc/pmu/sampling_tests/Makefile @@ -4,7 +4,7 @@ CFLAGS += -m64 TEST_GEN_PROGS := mmcr0_exceptionbits_test mmcr0_cc56run_test mmcr0_pmccext_test \ mmcr0_pmcjce_test mmcr0_fc56_pmc1ce_test mmcr0_fc56_pmc56_test \ mmcr1_comb_test mmcr2_l2l3_test mmcr2_fcs_fch_test \ - mmcr3_src_test mmcra_thresh_marked_sample_test + mmcr3_src_test mmcra_thresh_marked_sample_test mmcra_thresh_cmp_test top_srcdir = ../../../../../.. include ../../../lib.mk diff --git a/tools/testing/selftests/powerpc/pmu/sampling_tests/mmcra_thresh_cmp_test.c b/tools/testing/selftests/powerpc/pmu/sampling_tests/mmcra_thresh_cmp_test.c new file mode 100644 index ..904362f172c9 --- /dev/null +++ b/tools/testing/selftests/powerpc/pmu/sampling_tests/mmcra_thresh_cmp_test.c @@ -0,0 +1,74 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright 2022, Kajol Jain, IBM Corp. + */ + +#include +#include + +#include "../event.h" +#include "misc.h" +#include "utils.h" + +/* + * Primary PMU event used here is PM_MRK_INST_CMPL (0x401e0) + * Threshold event selection used is issue to complete for cycles + * Sampling criteria is Load only sampling + */ +#define p9_EventCode 0x13E35340401e0 +#define p10_EventCode 0x35340401e0 + +extern void thirty_two_instruction_loop_with_ll_sc(u64 loops, u64 *ll_sc_target); + +/* A perf sampling test to test mmcra fields */ +static int mmcra_thresh_cmp(void) +{ + struct event event; + u64 *intr_regs; + u64 dummy; + + /* Check for platform support for the test */ + SKIP_IF(check_pvr_for_sampling_tests()); + + /* Skip for comapt mode */ + SKIP_IF(check_for_compat_mode()); + + /* Init the event for the sampling test */ + if (!have_hwcap2(PPC_FEATURE2_ARCH_3_1)) { + event_init_sampling(, p9_EventCode); + } else { + event_init_sampling(, p10_EventCode); + event.attr.config1 = 1000; + } + + event.attr.sample_regs_intr = platform_extended_mask; + FAIL_IF(event_open()); + event.mmap_buffer = event_sample_buf_mmap(event.fd, 1); + + FAIL_IF(event_enable()); + + /* workload to make the event overflow */ + thirty_two_instruction_loop_with_ll_sc(100, ); + + FAIL_IF(event_disable()); + + /* Check for sample count */ + FAIL_IF(!collect_samples(event.mmap_buffer)); + + intr_regs = get_intr_regs(, event.mmap_buffer); + + /* Check for intr_regs */ + FAIL_IF(!intr_regs); + + /* Verify that thresh cmp match with the corresponding event code fields */ + FAIL_IF(get_thresh_cmp_val(event) != + get_mmcra_thd_cmp(get_reg_value(intr_regs, "MMCRA"), 4)); + + event_close(); + return 0; +} + +int main(void) +{ + FAIL_IF(test_harness(mmcra_thresh_cmp, "mmcra_thresh_cmp")); +} -- 2.31.1
[PATCH 02/35] testing/selftests/powerpc: Add support to fetch "platform" and "base platform" from auxv to detect platform.
From: Athira Rajeev The /proc/self/auxv contains information about "platform" on any system. Also "base platform" which is an indication about platform string corresponding to the real PVR. When systems are booted in compat mode, say, power10 booted in power9 mode, "platform" will point to power9 whereas base platform will point to power10. Incase, if the distro doesn't support platform indicated by real PVR, base platform will have a default value. The mismatch of platform/base platform is an indication of system booted in compat mode. In such cases, distro will have a Generic Compat registered which supports basic features for performance monitoring. Some of the selftest needs to be handled differently ( ex: generic events, alternative events, bhrb filter map) in Generic Compat PMU. Hence selftest framework needs utility functions to identify such cases. One way is make sure of auxv information. Below condition can be used to detect if Generic Compat PMU is registered. ie: <<>> if ((AT_PLATFORM != AT_BASE_PLATFORM) && (AT_BASE_PLATFORM != PVR)) <<>> this indicates Generic Compat PMU. Add utility function in "include/utils.h" to return: AT_PLATFORM and AT_BASE_PLATFORM from auxv. Also update misc.c in "sampling_tests" folder to add function to use above check to determine presence of generic compat pmu. In other architecture ( like x86 ), pmu_name is exposed via "/sys/bus/event_source/devices/cpu/caps". The same could be used in powerpc in future. Since currently we don't have the "caps" support in powerpc, patch uses auxv information to detect platform type and compat mode. But as placeholder utility function is added considering possiblity of getting "caps" information via sysfs. If that doesn't exist, fallback to using auxv information. Signed-off-by: Athira Rajeev --- .../testing/selftests/powerpc/include/utils.h | 10 .../powerpc/pmu/sampling_tests/misc.c | 50 +++ .../powerpc/pmu/sampling_tests/misc.h | 3 ++ 3 files changed, 63 insertions(+) diff --git a/tools/testing/selftests/powerpc/include/utils.h b/tools/testing/selftests/powerpc/include/utils.h index b7d188fc87c7..cf4763d3fc2d 100644 --- a/tools/testing/selftests/powerpc/include/utils.h +++ b/tools/testing/selftests/powerpc/include/utils.h @@ -74,6 +74,16 @@ static inline bool have_hwcap2(unsigned long ftr2) } #endif +static inline char *auxv_base_platform(void) +{ + return ((char *)get_auxv_entry(AT_BASE_PLATFORM)); +} + +static inline char *auxv_platform(void) +{ + return ((char *)get_auxv_entry(AT_PLATFORM)); +} + bool is_ppc64le(void); int using_hash_mmu(bool *using_hash); diff --git a/tools/testing/selftests/powerpc/pmu/sampling_tests/misc.c b/tools/testing/selftests/powerpc/pmu/sampling_tests/misc.c index 1afcd98f6036..eff56aa9f511 100644 --- a/tools/testing/selftests/powerpc/pmu/sampling_tests/misc.c +++ b/tools/testing/selftests/powerpc/pmu/sampling_tests/misc.c @@ -454,3 +454,53 @@ int get_thresh_cmp_val(struct event event) result = (exp << 8) | value; return result; } + +/* + * Utility function to check for generic compat PMU + * by comparing base_platform value from auxv and real + * PVR value. + */ +static bool auxv_generic_compat_pmu(void) +{ + int base_pvr = 0; + + if (!strcmp(auxv_base_platform(), "power9")) + base_pvr = POWER9; + else if (!strcmp(auxv_base_platform(), "power10")) + base_pvr = POWER10; + + return (!base_pvr); +} + +/* + * Check for generic compat PMU. + * First check for presence of pmu_name from + * "/sys/bus/event_source/devices/cpu/caps". + * If doesn't exist, fallback to using value + * auxv. + */ +bool check_for_generic_compat_pmu(void) +{ + char pmu_name[256]; + + memset(pmu_name, 0, sizeof(pmu_name)); + if (read_sysfs_file("bus/event_source/devices/cpu/caps/pmu_name", + pmu_name, sizeof(pmu_name)) < 0) + return auxv_generic_compat_pmu(); + + if (!strcmp(pmu_name, "generic_compat_pmu")) + return true; + else + return false; +} + +/* + * Check if system is booted in compat mode. + */ +bool check_for_compat_mode(void) +{ + char *platform = auxv_platform(); + char *base_platform = auxv_base_platform(); + + return strcmp(platform, base_platform); +} diff --git a/tools/testing/selftests/powerpc/pmu/sampling_tests/misc.h b/tools/testing/selftests/powerpc/pmu/sampling_tests/misc.h index 078120883fde..c0e923f38793 100644 --- a/tools/testing/selftests/powerpc/pmu/sampling_tests/misc.h +++ b/tools/testing/selftests/powerpc/pmu/sampling_tests/misc.h @@ -5,6 +5,7 @@ * Copyright 2022, Kajol Jain, IBM Corp. */ +#include #include "../event.h" #define POWER10 0x80 @@ -53,6 +54,8 @@ int collect_samples(void *sample_buff); u64 *get_intr_regs(struct event *event, void *sample_buff); u64 get_reg_value(u64 *intr_regs, char *register_name); int
[PATCH 01/35] selftest/powerpc/pmu: Add mask/shift bits for extracting threshold compare field
In power10, threshold compare field is not part of the raw event code and provided via event attribute config1. Hence add the mask and shift bits based on event attribute config1, to extract the threshold compare value for power10 Also add a new function called get_thresh_cmp_val to compute and return the threshold compare field for a given platform, since incase of power10, threshold compare value provided is decimal. Signed-off-by: Kajol Jain --- .../powerpc/pmu/sampling_tests/misc.c | 44 +++ .../powerpc/pmu/sampling_tests/misc.h | 1 + 2 files changed, 45 insertions(+) diff --git a/tools/testing/selftests/powerpc/pmu/sampling_tests/misc.c b/tools/testing/selftests/powerpc/pmu/sampling_tests/misc.c index fca054bbc094..1afcd98f6036 100644 --- a/tools/testing/selftests/powerpc/pmu/sampling_tests/misc.c +++ b/tools/testing/selftests/powerpc/pmu/sampling_tests/misc.c @@ -60,6 +60,8 @@ static void init_ev_encodes(void) switch (pvr) { case POWER10: + ev_mask_thd_cmp = 0x3; + ev_shift_thd_cmp = 0; ev_mask_rsq = 1; ev_shift_rsq = 9; ev_mask_comb = 3; @@ -410,3 +412,45 @@ u64 get_reg_value(u64 *intr_regs, char *register_name) return *(intr_regs + register_bit_position); } + +int get_thresh_cmp_val(struct event event) +{ + int exp = 0; + u64 result = 0; + u64 value; + + if (!have_hwcap2(PPC_FEATURE2_ARCH_3_1)) + return EV_CODE_EXTRACT(event.attr.config, thd_cmp); + + value = EV_CODE_EXTRACT(event.attr.config1, thd_cmp); + + if (!value) + return value; + + /* +* Incase of P10, thresh_cmp value is not part of raw event code +* and provided via attr.config1 parameter. To program threshold in MMCRA, +* take a 18 bit number N and shift right 2 places and increment +* the exponent E by 1 until the upper 10 bits of N are zero. +* Write E to the threshold exponent and write the lower 8 bits of N +* to the threshold mantissa. +* The max threshold that can be written is 261120. +*/ + if (value > 261120) + value = 261120; + while ((64 - __builtin_clzl(value)) > 8) { + exp++; + value >>= 2; + } + + /* +* Note that it is invalid to write a mantissa with the +* upper 2 bits of mantissa being zero, unless the +* exponent is also zero. +*/ + if (!(value & 0xC0) && exp) + result = -1; + else + result = (exp << 8) | value; + return result; +} diff --git a/tools/testing/selftests/powerpc/pmu/sampling_tests/misc.h b/tools/testing/selftests/powerpc/pmu/sampling_tests/misc.h index 7675f3177725..078120883fde 100644 --- a/tools/testing/selftests/powerpc/pmu/sampling_tests/misc.h +++ b/tools/testing/selftests/powerpc/pmu/sampling_tests/misc.h @@ -52,6 +52,7 @@ void *__event_read_samples(void *sample_buff, size_t *size, u64 *sample_count); int collect_samples(void *sample_buff); u64 *get_intr_regs(struct event *event, void *sample_buff); u64 get_reg_value(u64 *intr_regs, char *register_name); +int get_thresh_cmp_val(struct event event); static inline int get_mmcr0_fc56(u64 mmcr0, int pmc) { -- 2.31.1
[PATCH 00/35] Add group constraints and event code test as part of selftest
Patch series extends the perf interface selftests to cover scenarios for event code checking, group constraints, and also thresholding/branch related interface tests in sampling area. In this series, patches 1 to 14 adds additional tests under "powerpc/sampling_tests". These adds support for handling sample type PERF_SAMPLE_BRANCH_STACK along with interrupt regs. It adds utility functions and test for thresh_cmp and branch filters programmed in control register. Some of the tests needs to be skipped for "Generic Compat PMU" environment. Hence utility functions are added in "include/utils.c" and "sampling_tests/misc.h" to detect platform based on "auxv" entries. Currently in other architectures (like x86), the pmu_name is exposed via sysfs caps folder ie: "sys/bus/event_source/devices//caps". But in powerpc, "caps" is not supported. So, though the approach for detecting compat mode currently uses auxv, patchset adds an utility function considering a possibility of getting "caps" added for powerpc. Link to the patch to add support for caps under sysfs in powerpc: http://patchwork.ozlabs.org/project/linuxppc-dev/list/?series=297293 Patches 15 to 35 covers test related to group constraints and event codes. These new set of changes are added under new folder: "selftests/powerpc/pmu/event_code_tests" Patch 15 covers changes required for new folder with Makefile changes. The other patches add tests for perf interface to check the event group constraints, valid/invalid event codes, blacklisted events etc. Also add required utility functions under header file "misc.h" in sampling_tests folder. Patch 33 and 34 depend upon thresh_cmp group constraint fix patches sent in upstream mailing list. Link to the thresh_cmp fix patchset: http://patchwork.ozlabs.org/project/linuxppc-dev/list/?series=298742 Patch 13 of the patchset add selftest for mmcr1 pmcxsel/unit/cache fields, which was initially dropeed from sampling test patchset (patch number: 16) Link to the patch: http://patchwork.ozlabs.org/project/linuxppc-dev/patch/20220127072012.662451-17-kj...@linux.ibm.com/ Athira Rajeev (20): testing/selftests/powerpc: Add support to fetch "platform" and "base platform" from auxv to detect platform. selftest/powerpc/pmu: Refactor the platform check and add macros to find array size/PVR selftest/powerpc/pmu: Add selftest to check branch stack enablement will not crash on any platforms selftest/powerpc/pmu: Add selftest to check PERF_SAMPLE_REGS_INTR option will not crash on any platforms selftest/powerpc/pmu: Add selftest for checking valid and invalid bhrb filter maps selftest/powerpc/pmu: Add selftest for mmcr1 pmcxsel/unit/cache fields selftest/powerpc/pmu: Add support for perf event code tests selftest/powerpc/pmu: Add selftest for group constraint check for PMC5 and PMC6 selftest/powerpc/pmu: Add selftest to check PMC5/6 is excluded from some constraint checks selftest/powerpc/pmu: Add selftest to check constraint for number of counters in use. selftest/powerpc/pmu: Add selftest for group constraint check when using same PMC selftest/powerpc/pmu: Add selftest for group constraint check for radix_scope_qual field selftest/powerpc/pmu: Add selftest for group constraint for MMCRA Sampling Mode field selftest/powerpc/pmu: Add selftest for group constraint check MMCRA sample bits selftest/powerpc/pmu: Add selftest for checking invalid bits in event code selftest/powerpc/pmu: Add selftest for reserved bit check for MMCRA thresh_ctl field selftest/powerpc/pmu: Add selftest for blacklist events check in power9 selftest/powerpc/pmu: Add selftest for event alternatives for power9 selftest/powerpc/pmu: Add selftest for event alternatives for power10 selftest/powerpc/pmu: Add selftest for PERF_TYPE_HARDWARE events valid check Kajol Jain (15): selftest/powerpc/pmu: Add mask/shift bits for extracting threshold compare field selftest/powerpc/pmu: Add interface test for mmcra_thresh_cmp fields selftest/powerpc/pmu: Add support for branch sampling in get_intr_regs function selftest/powerpc/pmu: Add interface test for mmcra_ifm field of indirect call type selftest/powerpc/pmu: Add interface test for mmcra_ifm field for any branch type selftest/powerpc/pmu: Add interface test for mmcra_ifm field for conditional branch type selftest/powerpc/pmu: Add interface test for bhrb disable field selftest/powerpc/pmu: Add interface test for bhrb disable field for non-branch samples selftest/powerpc/pmu: Add selftest for group constraint check for MMCR0 l2l3_sel bits selftest/powerpc/pmu: Add selftest for group constraint check for MMCR1 cache bits selftest/powerpc/pmu: Add selftest for group constraint check for MMCRA thresh_cmp field selftest/powerpc/pmu: Add selftest for group constraint for unit and pmc field in p9 selftest/powerpc/pmu: Add selftest for group constraint
Re: [PATCH] bug: Use normal relative pointers in 'struct bug_entry'
On Thu, May 05, 2022 at 06:09:45PM -0700, Josh Poimboeuf wrote: > With CONFIG_GENERIC_BUG_RELATIVE_POINTERS, the addr/file relative > pointers are calculated weirdly: based on the beginning of the bug_entry > struct address, rather than their respective pointer addresses. > > Make the relative pointers less surprising to both humans and tools by > calculating them the normal way. > > Signed-off-by: Josh Poimboeuf Acked-by: Peter Zijlstra (Intel)
[PATCH kernel] KVM: PPC: Book3s: PR: Enable default TCE hypercalls
When KVM_CAP_PPC_ENABLE_HCALL was introduced, H_GET_TCE and H_PUT_TCE were already implemented and enabled by default; however H_GET_TCE was missed out on PR KVM (probably because the handler was in the real mode code at the time). This enables H_GET_TCE by default. While at this, this wraps the checks in ifdef CONFIG_SPAPR_TCE_IOMMU just like HV KVM. Signed-off-by: Alexey Kardashevskiy --- arch/powerpc/kvm/book3s_pr_papr.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/arch/powerpc/kvm/book3s_pr_papr.c b/arch/powerpc/kvm/book3s_pr_papr.c index dc4f51ac84bc..a1f2978b2a86 100644 --- a/arch/powerpc/kvm/book3s_pr_papr.c +++ b/arch/powerpc/kvm/book3s_pr_papr.c @@ -433,9 +433,12 @@ int kvmppc_hcall_impl_pr(unsigned long cmd) case H_REMOVE: case H_PROTECT: case H_BULK_REMOVE: +#ifdef CONFIG_SPAPR_TCE_IOMMU + case H_GET_TCE: case H_PUT_TCE: case H_PUT_TCE_INDIRECT: case H_STUFF_TCE: +#endif case H_CEDE: case H_LOGICAL_CI_LOAD: case H_LOGICAL_CI_STORE: @@ -464,7 +467,10 @@ static unsigned int default_hcall_list[] = { H_REMOVE, H_PROTECT, H_BULK_REMOVE, +#ifdef CONFIG_SPAPR_TCE_IOMMU + H_GET_TCE, H_PUT_TCE, +#endif H_CEDE, H_SET_MODE, #ifdef CONFIG_KVM_XICS -- 2.30.2
[PATCH RESEND] KVM: powerpc: remove extraneous asterisk from rm_host_ipi_action comment
kernel test robot reported kernel-doc warning for rm_host_ipi_action(): >> arch/powerpc/kvm/book3s_hv_rm_xics.c:887: warning: This comment starts with >> '/**', but isn't a kernel-doc comment. Refer >> Documentation/doc-guide/kernel-doc.rst * Host Operations poked by RM KVM Since the function is static, remove the extraneous (second) asterisk at the head of function comment. Fixes: 0c2a66062470cd ("KVM: PPC: Book3S HV: Host side kick VCPU when poked by real-mode KVM") Link: https://lore.kernel.org/linux-doc/202204252334.cd2isiii-...@intel.com/ Reported-by: kernel test robot Cc: Suresh Warrier Cc: Paul Mackerras Cc: Anders Roxell Cc: Greg Kroah-Hartman Cc: Arnd Bergmann Cc: Michael Ellerman Cc: Benjamin Herrenschmidt Cc: Nicholas Piggin Cc: Fabiano Rosas Cc: Paolo Bonzini Cc: Alexey Kardashevskiy Cc: linuxppc-dev@lists.ozlabs.org Cc: k...@vger.kernel.org Cc: sta...@vger.kernel.org # v5.15, v5.17 Cc: linux-ker...@vger.kernel.org Signed-off-by: Bagas Sanjaya --- arch/powerpc/kvm/book3s_hv_rm_xics.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/kvm/book3s_hv_rm_xics.c b/arch/powerpc/kvm/book3s_hv_rm_xics.c index 587c33fc45640f..6e16bd751c8423 100644 --- a/arch/powerpc/kvm/book3s_hv_rm_xics.c +++ b/arch/powerpc/kvm/book3s_hv_rm_xics.c @@ -883,7 +883,7 @@ long kvmppc_deliver_irq_passthru(struct kvm_vcpu *vcpu, /* --- Non-real mode XICS-related built-in routines --- */ -/** +/* * Host Operations poked by RM KVM */ static void rm_host_ipi_action(int action, void *data) base-commit: a7391ad3572431a354c927cf8896e86e50d7d0bf -- An old man doll... just what I always wanted! - Clara
[PATCH 2/2] powerpc/perf: Fix the threshold compare group constraint for power9
Thresh compare bits for a event is used to program thresh compare field in Monitor Mode Control Register A (MMCRA: 9-18 bits for power9). When scheduling events as a group, all events in that group should match value in threshold bits (like thresh compare, thresh control, thresh select). Otherwise event open for the sibling events should fail. But in the current code, incase thresh compare bits are not valid, we are not failing in group_constraint function which can result in invalid group schduling. Fix the issue by returning -1 incase event is threshold and threshold compare value is not valid. Thresh control bits in the event code is used to program thresh_ctl field in Monitor Mode Control Register A (MMCRA: 48-55). In below example, the scheduling of group events PM_MRK_INST_CMPL (873534401e0) and PM_THRESH_MET (8734340101ec) is expected to fail as both event request different thresh control bits and invalid thresh compare value. Result before the patch changes: [command]# perf stat -e "{r8735340401e0,r8734340101ec}" sleep 1 Performance counter stats for 'sleep 1': 11,048 r8735340401e0 1,967 r8734340101ec 1.001354036 seconds time elapsed 0.001421000 seconds user 0.0 seconds sys Result after the patch changes: [command]# perf stat -e "{r8735340401e0,r8734340101ec}" sleep 1 Error: The sys_perf_event_open() syscall returned with 22 (Invalid argument) for event (r8735340401e0). /bin/dmesg | grep -i perf may provide additional information. Fixes: 78a16d9fc1206 ("powerpc/perf: Avoid FAB_*_MATCH checks for power9") Signed-off-by: Kajol Jain --- arch/powerpc/perf/isa207-common.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/perf/isa207-common.c b/arch/powerpc/perf/isa207-common.c index 013b06af6fe6..bb5d64862bc9 100644 --- a/arch/powerpc/perf/isa207-common.c +++ b/arch/powerpc/perf/isa207-common.c @@ -508,7 +508,8 @@ int isa207_get_constraint(u64 event, unsigned long *maskp, unsigned long *valp, if (event_is_threshold(event) && is_thresh_cmp_valid(event)) { mask |= CNST_THRESH_MASK; value |= CNST_THRESH_VAL(event >> EVENT_THRESH_SHIFT); - } + } else if (event_is_threshold(event)) + return -1; } else { /* * Special case for PM_MRK_FAB_RSP_MATCH and PM_MRK_FAB_RSP_MATCH_CYC, -- 2.31.1
[PATCH 1/2] powerpc/perf: Fix the threshold compare group constraint for power10
Thresh compare bits for a event is used to program thresh compare field in Monitor Mode Control Register A (MMCRA: 8-18 bits for power10). When scheduling events as a group, all events in that group should match value in threshold bits. Otherwise event open for the sibling events should fail. But in the current code, incase thresh compare bits are not valid, we are not failing in group_constraint function which can result in invalid group schduling. Fix the issue by returning -1 incase event is threshold and threshold compare value is not valid in group_constraint function. Patch also fixes the p10_thresh_cmp_val function to return -1, incase threshold bits are not valid and changes corresponding check in is_thresh_cmp_valid function to return false only when the thresh_cmp value is less then 0. Thresh control bits in the event code is used to program thresh_ctl field in Monitor Mode Control Register A (MMCRA: 48-55). In below example, the scheduling of group events PM_MRK_INST_CMPL (3534401e0) and PM_THRESH_MET (34340101ec) is expected to fail as both event request different thresh control bits. Result before the patch changes: [command]# perf stat -e "{r35340401e0,r34340101ec}" sleep 1 Performance counter stats for 'sleep 1': 8,482 r35340401e0 0 r34340101ec 1.001474838 seconds time elapsed 0.001145000 seconds user 0.0 seconds sys Result after the patch changes: [command]# perf stat -e "{r35340401e0,r34340101ec}" sleep 1 Performance counter stats for 'sleep 1': r35340401e0 r34340101ec 1.001499607 seconds time elapsed 0.000204000 seconds user 0.00076 seconds sys Fixes: 82d2c16b350f7 ("powerpc/perf: Adds support for programming of Thresholding in P10") Signed-off-by: Kajol Jain --- arch/powerpc/perf/isa207-common.c | 9 + 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/perf/isa207-common.c b/arch/powerpc/perf/isa207-common.c index a74d382ecbb7..013b06af6fe6 100644 --- a/arch/powerpc/perf/isa207-common.c +++ b/arch/powerpc/perf/isa207-common.c @@ -108,7 +108,7 @@ static void mmcra_sdar_mode(u64 event, unsigned long *mmcra) *mmcra |= MMCRA_SDAR_MODE_TLB; } -static u64 p10_thresh_cmp_val(u64 value) +static int p10_thresh_cmp_val(u64 value) { int exp = 0; u64 result = value; @@ -139,7 +139,7 @@ static u64 p10_thresh_cmp_val(u64 value) * exponent is also zero. */ if (!(value & 0xC0) && exp) - result = 0; + result = -1; else result = (exp << 8) | value; } @@ -187,7 +187,7 @@ static bool is_thresh_cmp_valid(u64 event) unsigned int cmp, exp; if (cpu_has_feature(CPU_FTR_ARCH_31)) - return p10_thresh_cmp_val(event) != 0; + return p10_thresh_cmp_val(event) >= 0; /* * Check the mantissa upper two bits are not zero, unless the @@ -502,7 +502,8 @@ int isa207_get_constraint(u64 event, unsigned long *maskp, unsigned long *valp, value |= CNST_THRESH_CTL_SEL_VAL(event >> EVENT_THRESH_SHIFT); mask |= p10_CNST_THRESH_CMP_MASK; value |= p10_CNST_THRESH_CMP_VAL(p10_thresh_cmp_val(event_config1)); - } + } else if (event_is_threshold(event)) + return -1; } else if (cpu_has_feature(CPU_FTR_ARCH_300)) { if (event_is_threshold(event) && is_thresh_cmp_valid(event)) { mask |= CNST_THRESH_MASK; -- 2.31.1