From: "Nicholas Piggin" <npiggin@gmail.com>
To: "Thomas Huth" <thuth@redhat.com>, <kvm@vger.kernel.org>
Cc: <linuxppc-dev@lists.ozlabs.org>,
"Laurent Vivier" <lvivier@redhat.com>,
"Shaoqin Huang" <shahuang@redhat.com>,
"Andrew Jones" <andrew.jones@linux.dev>,
"Nico Boehr" <nrb@linux.ibm.com>
Subject: Re: [kvm-unit-tests PATCH v5 24/29] powerpc: interrupt tests
Date: Fri, 22 Dec 2023 19:58:45 +1000 [thread overview]
Message-ID: <CXURVO6COZBK.2YISETA5D0C2@wheely> (raw)
In-Reply-To: <feab6612-31f6-41bd-8ee9-89a19aa0e76c@redhat.com>
On Tue Dec 19, 2023 at 11:57 PM AEST, Thomas Huth wrote:
> On 16/12/2023 14.42, Nicholas Piggin wrote:
> > Add basic testing of various kinds of interrupts, machine check,
> > page fault, illegal, decrementer, trace, syscall, etc.
> >
> > This has a known failure on QEMU TCG pseries machines where MSR[ME]
> > can be incorrectly set to 0.
> >
> > Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
> > ---
> > lib/powerpc/asm/ppc_asm.h | 21 +-
> > powerpc/Makefile.common | 3 +-
> > powerpc/interrupts.c | 422 ++++++++++++++++++++++++++++++++++++++
> > powerpc/unittests.cfg | 3 +
> > 4 files changed, 445 insertions(+), 4 deletions(-)
> > create mode 100644 powerpc/interrupts.c
> >
> > diff --git a/lib/powerpc/asm/ppc_asm.h b/lib/powerpc/asm/ppc_asm.h
> > index ef2d91dd..778e78ee 100644
> > --- a/lib/powerpc/asm/ppc_asm.h
> > +++ b/lib/powerpc/asm/ppc_asm.h
> > @@ -35,17 +35,32 @@
> >
> > #endif /* __BYTE_ORDER__ */
> >
> > +#define SPR_DSISR 0x012
> > +#define SPR_DAR 0x013
> > +#define SPR_DEC 0x016
> > +#define SPR_SRR0 0x01A
> > +#define SPR_SRR1 0x01B
> > +#define SPR_FSCR 0x099
> > +#define FSCR_PREFIX 0x2000
> > +#define SPR_HDEC 0x136
> > #define SPR_HSRR0 0x13A
> > #define SPR_HSRR1 0x13B
> > +#define SPR_LPCR 0x13E
> > +#define LPCR_HDICE 0x1UL
> > +#define SPR_HEIR 0x153
> > +#define SPR_SIAR 0x31C
> >
> > /* Machine State Register definitions: */
> > #define MSR_LE_BIT 0
> > #define MSR_EE_BIT 15 /* External Interrupts Enable */
> > #define MSR_HV_BIT 60 /* Hypervisor mode */
> > #define MSR_SF_BIT 63 /* 64-bit mode */
> > -#define MSR_ME 0x1000ULL
> >
> > -#define SPR_HSRR0 0x13A
> > -#define SPR_HSRR1 0x13B
> > +#define MSR_DR 0x0010ULL
> > +#define MSR_IR 0x0020ULL
> > +#define MSR_BE 0x0200ULL /* Branch Trace Enable */
> > +#define MSR_SE 0x0400ULL /* Single Step Enable */
> > +#define MSR_EE 0x8000ULL
> > +#define MSR_ME 0x1000ULL
> >
> > #endif /* _ASMPOWERPC_PPC_ASM_H */
> > diff --git a/powerpc/Makefile.common b/powerpc/Makefile.common
> > index a7af225b..b340a53b 100644
> > --- a/powerpc/Makefile.common
> > +++ b/powerpc/Makefile.common
> > @@ -11,7 +11,8 @@ tests-common = \
> > $(TEST_DIR)/rtas.elf \
> > $(TEST_DIR)/emulator.elf \
> > $(TEST_DIR)/tm.elf \
> > - $(TEST_DIR)/sprs.elf
> > + $(TEST_DIR)/sprs.elf \
> > + $(TEST_DIR)/interrupts.elf
> >
> > tests-all = $(tests-common) $(tests)
> > all: directories $(TEST_DIR)/boot_rom.bin $(tests-all)
> > diff --git a/powerpc/interrupts.c b/powerpc/interrupts.c
> > new file mode 100644
> > index 00000000..3217b15e
> > --- /dev/null
> > +++ b/powerpc/interrupts.c
> > @@ -0,0 +1,422 @@
> > +/*
> > + * Test interrupts
> > + *
> > + * This work is licensed under the terms of the GNU LGPL, version 2.
> > + */
> > +#include <libcflat.h>
> > +#include <util.h>
> > +#include <migrate.h>
> > +#include <alloc.h>
> > +#include <asm/handlers.h>
> > +#include <asm/hcall.h>
> > +#include <asm/processor.h>
> > +#include <asm/barrier.h>
> > +
> > +#define SPR_LPCR 0x13E
> > +#define LPCR_HDICE 0x1UL
> > +#define SPR_DEC 0x016
> > +#define SPR_HDEC 0x136
> > +
> > +#define MSR_DR 0x0010ULL
> > +#define MSR_IR 0x0020ULL
> > +#define MSR_EE 0x8000ULL
> > +#define MSR_ME 0x1000ULL
>
> Why don't you use the definitions from ppc_asm.h above?
Yeah, should be more consistent with those. I'll take a look.
>
> > +static bool cpu_has_heir(void)
> > +{
> > + uint32_t pvr = mfspr(287); /* Processor Version Register */
> > +
> > + if (!machine_is_powernv())
> > + return false;
> > +
> > + /* POWER6 has HEIR, but QEMU powernv support does not go that far */
> > + switch (pvr >> 16) {
> > + case 0x4b: /* POWER8E */
> > + case 0x4c: /* POWER8NVL */
> > + case 0x4d: /* POWER8 */
> > + case 0x4e: /* POWER9 */
> > + case 0x80: /* POWER10 */
>
> I'd suggest to introduce some #defines for those PVR values instead of using
> magic numbers all over the place?
Yeah you're right.
>
> > + return true;
> > + default:
> > + return false;
> > + }
> > +}
> > +
> > +static bool cpu_has_prefix(void)
> > +{
> > + uint32_t pvr = mfspr(287); /* Processor Version Register */
> > + switch (pvr >> 16) {
> > + case 0x80: /* POWER10 */
> > + return true;
> > + default:
> > + return false;
> > + }
> > +}
> > +
> > +static bool cpu_has_lev_in_srr1(void)
> > +{
> > + uint32_t pvr = mfspr(287); /* Processor Version Register */
> > + switch (pvr >> 16) {
> > + case 0x80: /* POWER10 */
> > + return true;
> > + default:
> > + return false;
> > + }
> > +}
> > +
> > +static bool regs_is_prefix(volatile struct pt_regs *regs)
> > +{
> > + return (regs->msr >> (63-34)) & 1;
>
> You introduced a bunch of new #define MSR_xx statements ... why not for this
> one, too?
It's an interrupt-specific bit so SRR1_xx, but yes it should be a
define.
>
> > +}
> > +
> > +static void regs_advance_insn(struct pt_regs *regs)
> > +{
> > + if (regs_is_prefix(regs))
> > + regs->nip += 8;
> > + else
> > + regs->nip += 4;
> > +}
> > +
> > +static volatile bool got_interrupt;
> > +static volatile struct pt_regs recorded_regs;
> > +
> > +static void mce_handler(struct pt_regs *regs, void *opaque)
> > +{
> > + got_interrupt = true;
> > + memcpy((void *)&recorded_regs, regs, sizeof(struct pt_regs));
> > + regs_advance_insn(regs);
> > +}
> > +
> > +static void test_mce(void)
> > +{
> > + unsigned long addr = -4ULL;
> > + uint8_t tmp;
> > +
> > + handle_exception(0x200, mce_handler, NULL);
> > +
> > + if (machine_is_powernv()) {
> > + enable_mcheck();
> > + } else {
> > + report(mfmsr() & MSR_ME, "pseries machine has MSR[ME]=1");
> > + if (!(mfmsr() & MSR_ME)) { /* try to fix it */
> > + enable_mcheck();
> > + }
> > + if (mfmsr() & MSR_ME) {
> > + disable_mcheck();
> > + report(mfmsr() & MSR_ME, "pseries is unable to change MSR[ME]");
> > + if (!(mfmsr() & MSR_ME)) { /* try to fix it */
> > + enable_mcheck();
> > + }
> > + }
> > + }
> > +
> > + asm volatile("lbz %0,0(%1)" : "=r"(tmp) : "r"(addr));
> > +
> > + report(got_interrupt, "MCE on access to invalid real address");
> > + report(mfspr(SPR_DAR) == addr, "MCE sets DAR correctly");
> > + got_interrupt = false;
> > +}
> > +
> > +static void dseg_handler(struct pt_regs *regs, void *data)
> > +{
> > + got_interrupt = true;
> > + memcpy((void *)&recorded_regs, regs, sizeof(struct pt_regs));
> > + regs_advance_insn(regs);
> > + regs->msr &= ~MSR_DR;
> > +}
> > +
> > +static void test_dseg(void)
> > +{
> > + uint64_t msr, tmp;
> > +
> > + report_prefix_push("data segment");
> > +
> > + /* Some HV start in radix mode and need 0x300 */
> > + handle_exception(0x300, &dseg_handler, NULL);
> > + handle_exception(0x380, &dseg_handler, NULL);
> > +
> > + asm volatile(
> > +" mfmsr %0 \n \
> > + ori %0,%0,%2 \n \
> > + mtmsrd %0 \n \
> > + lbz %1,0(0) "
> > + : "=r"(msr), "=r"(tmp) : "i"(MSR_DR): "memory");
> > +
> > + report(got_interrupt, "interrupt on NULL dereference");
> > + got_interrupt = false;
> > +
> > + handle_exception(0x300, NULL, NULL);
> > + handle_exception(0x380, NULL, NULL);
> > +
> > + report_prefix_pop();
> > +}
> > +
> > +static void dec_handler(struct pt_regs *regs, void *data)
> > +{
> > + got_interrupt = true;
> > + memcpy((void *)&recorded_regs, regs, sizeof(struct pt_regs));
> > + regs->msr &= ~MSR_EE;
> > +}
> > +
> > +static void test_dec(void)
> > +{
> > + uint64_t msr;
> > +
> > + report_prefix_push("decrementer");
> > +
> > + handle_exception(0x900, &dec_handler, NULL);
> > +
> > + asm volatile(
> > +" mtdec %1 \n \
> > + mfmsr %0 \n \
> > + ori %0,%0,%2 \n \
> > + mtmsrd %0,1 "
> > + : "=r"(msr) : "r"(10000), "i"(MSR_EE): "memory");
> > +
> > + while (!got_interrupt)
> > + ;
>
> Maybe add a timeout (in case the interrupt never fires)?
Yeah that would improve things.
> > + report(got_interrupt, "interrupt on decrementer underflow");
> > + got_interrupt = false;
> > +
> > + handle_exception(0x900, NULL, NULL);
> > +
> > + if (!machine_is_powernv())
> > + goto done;
> > +
> > + handle_exception(0x980, &dec_handler, NULL);
> > +
> > + mtspr(SPR_LPCR, mfspr(SPR_LPCR) | LPCR_HDICE);
> > + asm volatile(
> > +" mtspr 0x136,%1 \n \
> > + mtdec %3 \n \
> > + mfmsr %0 \n \
> > + ori %0,%0,%2 \n \
> > + mtmsrd %0,1 "
> > + : "=r"(msr) : "r"(10000), "i"(MSR_EE), "r"(0x7fffffff): "memory");
> > +
> > + while (!got_interrupt)
> > + ;
>
> dito?
Will do.
Thanks,
Nick
next prev parent reply other threads:[~2023-12-22 9:58 UTC|newest]
Thread overview: 53+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-12-16 13:42 [kvm-unit-tests PATCH v5 00/29] powerpc: updates, P10, PNV support Nicholas Piggin
2023-12-16 13:42 ` [kvm-unit-tests PATCH v5 01/29] arch-run: Clean up temporary files properly Nicholas Piggin
2023-12-16 13:42 ` [kvm-unit-tests PATCH v5 02/29] arch-run: Clean up initrd cleanup Nicholas Piggin
2023-12-16 13:42 ` [kvm-unit-tests PATCH v5 03/29] migration: use a more robust way to wait for background job Nicholas Piggin
2023-12-16 13:42 ` [kvm-unit-tests PATCH v5 04/29] migration: Support multiple migrations Nicholas Piggin
2023-12-16 13:42 ` [kvm-unit-tests PATCH v5 05/29] arch-run: rename migration variables Nicholas Piggin
2023-12-16 13:42 ` [kvm-unit-tests PATCH v5 06/29] powerpc: Quiet QEMU TCG pseries capability warnings Nicholas Piggin
2023-12-19 5:55 ` Thomas Huth
2023-12-16 13:42 ` [kvm-unit-tests PATCH v5 07/29] powerpc: Add a migration stress tester Nicholas Piggin
2023-12-19 5:58 ` Thomas Huth
2023-12-22 10:32 ` Nicholas Piggin
2023-12-16 13:42 ` [kvm-unit-tests PATCH v5 08/29] powerpc: Require KVM for the TM test Nicholas Piggin
2023-12-19 5:59 ` Thomas Huth
2023-12-16 13:42 ` [kvm-unit-tests PATCH v5 09/29] powerpc: Fix interrupt stack alignment Nicholas Piggin
2023-12-19 6:09 ` Thomas Huth
2023-12-16 13:42 ` [kvm-unit-tests PATCH v5 10/29] powerpc/sprs: Specify SPRs with data rather than code Nicholas Piggin
2023-12-19 6:14 ` Thomas Huth
2023-12-22 10:32 ` Nicholas Piggin
2023-12-16 13:42 ` [kvm-unit-tests PATCH v5 11/29] powerpc/sprs: Don't fail changed SPRs that are used by the test harness Nicholas Piggin
2023-12-19 11:34 ` Thomas Huth
2023-12-16 13:42 ` [kvm-unit-tests PATCH v5 12/29] powerpc/sprs: Avoid taking async interrupts caused by register fuzzing Nicholas Piggin
2023-12-19 11:47 ` Thomas Huth
2023-12-22 9:51 ` Nicholas Piggin
2023-12-16 13:42 ` [kvm-unit-tests PATCH v5 13/29] powerpc: Make interrupt handler error more readable Nicholas Piggin
2023-12-19 11:53 ` Thomas Huth
2023-12-22 9:52 ` Nicholas Piggin
2023-12-16 13:42 ` [kvm-unit-tests PATCH v5 14/29] powerpc: Expand exception handler vector granularity Nicholas Piggin
2023-12-19 11:55 ` Thomas Huth
2023-12-16 13:42 ` [kvm-unit-tests PATCH v5 15/29] powerpc: Add support for more interrupts including HV interrupts Nicholas Piggin
2023-12-16 13:42 ` [kvm-unit-tests PATCH v5 16/29] powerpc: Set .got section alignment to 256 bytes Nicholas Piggin
2023-12-19 12:01 ` Thomas Huth
2023-12-16 13:42 ` [kvm-unit-tests PATCH v5 17/29] powerpc: Discover runtime load address dynamically Nicholas Piggin
2023-12-16 13:42 ` [kvm-unit-tests PATCH v5 18/29] powerpc: Fix stack backtrace termination Nicholas Piggin
2023-12-19 12:22 ` Thomas Huth
2023-12-22 9:55 ` Nicholas Piggin
2023-12-16 13:42 ` [kvm-unit-tests PATCH v5 19/29] scripts: allow machine option to be specified in unittests.cfg Nicholas Piggin
2023-12-19 12:27 ` Thomas Huth
2023-12-16 13:42 ` [kvm-unit-tests PATCH v5 20/29] scripts: Accommodate powerpc powernv machine differences Nicholas Piggin
2023-12-19 12:36 ` Thomas Huth
2023-12-16 13:42 ` [kvm-unit-tests PATCH v5 21/29] powerpc: Support powernv machine with QEMU TCG Nicholas Piggin
2023-12-16 13:42 ` [kvm-unit-tests PATCH v5 22/29] powerpc: Fix emulator illegal instruction test for powernv Nicholas Piggin
2023-12-19 12:39 ` Thomas Huth
2023-12-16 13:42 ` [kvm-unit-tests PATCH v5 23/29] powerpc/sprs: Test hypervisor registers on powernv machine Nicholas Piggin
2023-12-16 13:42 ` [kvm-unit-tests PATCH v5 24/29] powerpc: interrupt tests Nicholas Piggin
2023-12-19 13:57 ` Thomas Huth
2023-12-22 9:58 ` Nicholas Piggin [this message]
2023-12-16 13:42 ` [kvm-unit-tests PATCH v5 25/29] powerpc: Add rtas stop-self support Nicholas Piggin
2023-12-19 14:15 ` Thomas Huth
2023-12-16 13:42 ` [kvm-unit-tests PATCH v5 26/29] powerpc: add SMP and IPI support Nicholas Piggin
2023-12-16 13:42 ` [kvm-unit-tests PATCH v5 27/29] powerpc: Avoid using larx/stcx. in spinlocks when only one CPU is running Nicholas Piggin
2023-12-16 13:42 ` [kvm-unit-tests PATCH v5 28/29] powerpc: Add atomics tests Nicholas Piggin
2023-12-16 13:42 ` [kvm-unit-tests PATCH v5 29/29] powerpc: Add timebase tests Nicholas Piggin
2023-12-19 14:23 ` Thomas Huth
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=CXURVO6COZBK.2YISETA5D0C2@wheely \
--to=npiggin@gmail.com \
--cc=andrew.jones@linux.dev \
--cc=kvm@vger.kernel.org \
--cc=linuxppc-dev@lists.ozlabs.org \
--cc=lvivier@redhat.com \
--cc=nrb@linux.ibm.com \
--cc=shahuang@redhat.com \
--cc=thuth@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox