From: David Gibson <david@gibson.dropbear.id.au>
To: Aravinda Prasad <aravinda@linux.vnet.ibm.com>
Cc: qemu-ppc@nongnu.org, qemu-devel@nongnu.org, aik@ozlabs.ru,
mahesh@linux.vnet.ibm.com, benh@au1.ibm.com, paulus@samba.org,
sam.bobroff@au1.ibm.com
Subject: Re: [Qemu-devel] [PATCH v3 4/5] target/ppc: Handle NMI guest exit
Date: Thu, 17 Aug 2017 11:57:35 +1000 [thread overview]
Message-ID: <20170817015735.GD5509@umbus.fritz.box> (raw)
In-Reply-To: <150287475974.9760.13295593936611613542.stgit@aravinda>
[-- Attachment #1: Type: text/plain, Size: 9085 bytes --]
On Wed, Aug 16, 2017 at 02:42:39PM +0530, Aravinda Prasad wrote:
> Memory error such as bit flips that cannot be corrected
> by hardware are passed on to the kernel for handling.
> If the memory address in error belongs to guest then
> guest kernel is responsible for taking suitable action.
> Patch [1] enhances KVM to exit guest with exit reason
> set to KVM_EXIT_NMI in such cases.
>
> This patch handles KVM_EXIT_NMI exit. If the guest OS
> has registered the machine check handling routine by
> calling "ibm,nmi-register", then the handler builds
> the error log and invokes the registered handler else
> invokes the handler at 0x200.
>
> [1] https://www.spinics.net/lists/kvm-ppc/msg12637.html
> (e20bbd3d and related commits)
>
> Signed-off-by: Aravinda Prasad <aravinda@linux.vnet.ibm.com>
> ---
> hw/ppc/spapr.c | 4 ++
> target/ppc/kvm.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++
> target/ppc/kvm_ppc.h | 81 +++++++++++++++++++++++++++++++++++++++++++++++
> 3 files changed, 171 insertions(+)
>
> diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
> index 0bb2c4a..6cc3f69 100644
> --- a/hw/ppc/spapr.c
> +++ b/hw/ppc/spapr.c
> @@ -2346,6 +2346,10 @@ static void ppc_spapr_init(MachineState *machine)
> error_report("Could not get size of LPAR rtas '%s'", filename);
> exit(1);
> }
> +
> + /* Resize blob to accommodate error log. */
> + spapr->rtas_size = RTAS_ERRLOG_OFFSET + sizeof(struct RtasMCELog);
> +
> spapr->rtas_blob = g_malloc(spapr->rtas_size);
> if (load_image_size(filename, spapr->rtas_blob, spapr->rtas_size) < 0) {
> error_report("Could not load LPAR rtas '%s'", filename);
> diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c
> index 8571379..73f64ed 100644
> --- a/target/ppc/kvm.c
> +++ b/target/ppc/kvm.c
> @@ -1782,6 +1782,11 @@ int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
> ret = 0;
> break;
>
> + case KVM_EXIT_NMI:
> + DPRINTF("handle NMI exception\n");
> + ret = kvm_handle_nmi(cpu);
> + break;
> +
> default:
> fprintf(stderr, "KVM: unknown exit reason %d\n", run->exit_reason);
> ret = -1;
> @@ -2704,6 +2709,87 @@ int kvm_arch_msi_data_to_gsi(uint32_t data)
> return data & 0xffff;
> }
>
> +int kvm_handle_nmi(PowerPCCPU *cpu)
So you only handle NMIs with KVM. Wouldn't it make sense to also
handle them for TCG (where they can be triggered with the "nmi"
command on the monitor).
> +{
> + struct RtasMCELog mc_log;
> + CPUPPCState *env = &cpu->env;
> + sPAPRMachineState *spapr = SPAPR_MACHINE(qdev_get_machine());
> + PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cpu);
> + target_ulong msr = 0;
> +
> + cpu_synchronize_state(CPU(cpu));
> +
> + /*
> + * Properly set bits in MSR before we invoke the handler.
> + * SRR0/1, DAR and DSISR are properly set by KVM
> + */
> + if (!(*pcc->interrupts_big_endian)(cpu)) {
> + msr |= (1ULL << MSR_LE);
> + }
> +
> + if (env->msr && (1ULL << MSR_SF)) {
> + msr |= (1ULL << MSR_SF);
> + }
> +
> + msr |= (1ULL << MSR_ME);
> + env->msr = msr;
> +
> + if (!spapr->guest_machine_check_addr) {
> + /*
> + * If OS has not registered with "ibm,nmi-register"
> + * jump to 0x200
> + */
> + env->nip = 0x200;
> + return 0;
> + }
> +
> + while (spapr->mc_in_progress) {
> + /*
> + * Check whether the same CPU got machine check error
> + * while still handling the mc error (i.e., before
> + * that CPU called "ibm,nmi-interlock"
> + */
> + if (spapr->mc_cpu == cpu->cpu_dt_id) {
> + qemu_system_guest_panicked(NULL);
> + }
> + qemu_cond_wait_iothread(&spapr->mc_delivery_cond);
> + }
> + spapr->mc_in_progress = true;
> + spapr->mc_cpu = cpu->cpu_dt_id;
This will be merging against 2.11 and there are changes to the use of
cpu_dt_id in the ppc-for-2.11 tree which you'll need to rebase on top
of.
> + /* Set error log fields */
> + mc_log.r3 = env->gpr[3];
> + mc_log.err_log.byte0 = 0;
> + mc_log.err_log.byte1 =
> + (RTAS_SEVERITY_ERROR_SYNC << RTAS_ELOG_SEVERITY_SHIFT);
> + mc_log.err_log.byte1 |=
> + (RTAS_DISP_NOT_RECOVERED << RTAS_ELOG_DISPOSITION_SHIFT);
> + mc_log.err_log.byte2 =
> + (RTAS_INITIATOR_MEMORY << RTAS_ELOG_INITIATOR_SHIFT);
> + mc_log.err_log.byte2 |= RTAS_TARGET_MEMORY;
> +
> + if (env->spr[SPR_DSISR] & P7_DSISR_MC_UE) {
> + mc_log.err_log.byte3 = RTAS_TYPE_ECC_UNCORR;
> + } else {
> + mc_log.err_log.byte3 = 0;
> + }
> +
> + /* Handle all Host/Guest LE/BE combinations */
> + if (env->msr & (1ULL << MSR_LE)) {
> + mc_log.r3 = cpu_to_le64(mc_log.r3);
> + } else {
> + mc_log.r3 = cpu_to_be64(mc_log.r3);
> + }
So, the r3 field is guest order, but the rest is fixed BE order, is
that right?
> + cpu_physical_memory_write(spapr->rtas_addr + RTAS_ERRLOG_OFFSET,
> + &mc_log, sizeof(mc_log));
> +
You never set extended_log_length, so it doesn't look like the whole
structure is initialized.
> + env->nip = spapr->guest_machine_check_addr;
> + env->gpr[3] = spapr->rtas_addr + RTAS_ERRLOG_OFFSET;
> + return 0;
> +}
> +
> int kvmppc_enable_hwrng(void)
> {
> if (!kvm_enabled() || !kvm_check_extension(kvm_state, KVM_CAP_PPC_HWRNG)) {
> diff --git a/target/ppc/kvm_ppc.h b/target/ppc/kvm_ppc.h
> index 6bc6fb3..bc8e3ce 100644
> --- a/target/ppc/kvm_ppc.h
> +++ b/target/ppc/kvm_ppc.h
> @@ -70,6 +70,87 @@ void kvmppc_update_sdr1(target_ulong sdr1);
>
> bool kvmppc_is_mem_backend_page_size_ok(const char *obj_path);
>
> +int kvm_handle_nmi(PowerPCCPU *cpu);
> +
> +/* Offset from rtas-base where error log is placed */
> +#define RTAS_ERRLOG_OFFSET 0x200
> +
> +#define RTAS_ELOG_SEVERITY_SHIFT 0x5
> +#define RTAS_ELOG_DISPOSITION_SHIFT 0x3
> +#define RTAS_ELOG_INITIATOR_SHIFT 0x4
> +
> +/*
> + * Only required RTAS event severity, disposition, initiator
> + * target and type are copied from arch/powerpc/include/asm/rtas.h
> + */
> +
> +/* RTAS event severity */
> +#define RTAS_SEVERITY_ERROR_SYNC 0x3
> +
> +/* RTAS event disposition */
> +#define RTAS_DISP_NOT_RECOVERED 0x2
> +
> +/* RTAS event initiator */
> +#define RTAS_INITIATOR_MEMORY 0x4
> +
> +/* RTAS event target */
> +#define RTAS_TARGET_MEMORY 0x4
> +
> +/* RTAS event type */
> +#define RTAS_TYPE_ECC_UNCORR 0x09
> +
> +/*
> + * Currently KVM only passes on the uncorrected machine
> + * check memory error to guest. Other machine check errors
> + * such as SLB multi-hit and TLB multi-hit are recovered
> + * in KVM and are not passed on to guest.
> + *
> + * DSISR Bit for uncorrected machine check error. Based
> + * on arch/powerpc/include/asm/mce.h
> + */
> +#define PPC_BIT(bit) (0x8000000000000000ULL >> bit)
> +#define P7_DSISR_MC_UE (PPC_BIT(48)) /* P8 too */
> +
> +/* Adopted from kernel source arch/powerpc/include/asm/rtas.h */
> +struct rtas_error_log {
There are already structures for rtas error logs in
hw/ppc/spapr_events.c; those should be re-used. You can probably
share some code to transfer log entries to the guest with correct
endianness as well.
> + /* Byte 0 */
> + uint8_t byte0; /* Architectural version */
> +
> + /* Byte 1 */
> + uint8_t byte1;
> + /* XXXXXXXX
> + * XXX 3: Severity level of error
> + * XX 2: Degree of recovery
> + * X 1: Extended log present?
> + * XX 2: Reserved
> + */
> +
> + /* Byte 2 */
> + uint8_t byte2;
> + /* XXXXXXXX
> + * XXXX 4: Initiator of event
> + * XXXX 4: Target of failed operation
> + */
> + uint8_t byte3; /* General event or error*/
> + __be32 extended_log_length; /* length in bytes */
> + unsigned char buffer[1]; /* Start of extended log */
> + /* Variable length. */
> +};
> +
> +/*
> + * Data format in RTAS-Blob
> + *
> + * This structure contains error information related to Machine
> + * Check exception. This is filled up and copied to rtas-blob
> + * upon machine check exception. The address of rtas-blob is
> + * passed on to OS registered machine check notification
> + * routines upon machine check exception
> + */
> +struct RtasMCELog {
> + target_ulong r3;
> + struct rtas_error_log err_log;
> +};
> +
> #else
>
> static inline uint32_t kvmppc_get_tbfreq(void)
>
--
David Gibson | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you. NOT _the_ _other_
| _way_ _around_!
http://www.ozlabs.org/~dgibson
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
next prev parent reply other threads:[~2017-08-17 2:00 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-08-16 9:11 [Qemu-devel] [PATCH v3 0/5] target-ppc/spapr: Add FWNMI support in QEMU for PowerKVM guests Aravinda Prasad
2017-08-16 9:12 ` [Qemu-devel] [PATCH v3 1/5] ppc: spapr: Register and handle HCALL to receive updated RTAS region Aravinda Prasad
2017-08-17 1:34 ` David Gibson
2017-08-17 10:27 ` Nikunj A Dadhania
2017-08-21 9:42 ` Aravinda Prasad
2017-08-22 3:33 ` David Gibson
2017-08-22 7:16 ` Aravinda Prasad
2017-08-16 9:12 ` [Qemu-devel] [PATCH v3 2/5] ppc: spapr: Handle "ibm, nmi-register" and "ibm, nmi-interlock" RTAS calls Aravinda Prasad
2017-08-17 1:39 ` David Gibson
2017-08-21 12:35 ` Aravinda Prasad
2017-08-22 2:08 ` David Gibson
2017-08-22 7:12 ` Aravinda Prasad
2017-09-21 9:09 ` Aravinda Prasad
2017-09-27 7:15 ` David Gibson
2017-09-27 11:53 ` Aravinda Prasad
2017-09-28 3:58 ` David Gibson
2017-08-16 9:12 ` [Qemu-devel] [PATCH v3 3/5] Wrapper function to wait on condition for the main loop mutex Aravinda Prasad
2017-08-16 9:12 ` [Qemu-devel] [PATCH v3 4/5] target/ppc: Handle NMI guest exit Aravinda Prasad
2017-08-17 1:57 ` David Gibson [this message]
2017-08-21 12:30 ` Aravinda Prasad
2017-08-23 8:39 ` David Gibson
2017-09-08 8:09 ` [Qemu-devel] [Qemu-ppc] " Aravinda Prasad
2017-09-10 3:22 ` David Gibson
2017-08-16 9:12 ` [Qemu-devel] [PATCH v3 5/5] ppc: spapr: Enable FWNMI capability Aravinda Prasad
2017-08-17 1:59 ` David Gibson
2017-08-21 10:50 ` Aravinda Prasad
2017-08-16 9:29 ` [Qemu-devel] [PATCH v3 0/5] target-ppc/spapr: Add FWNMI support in QEMU for PowerKVM guests no-reply
2017-08-16 9:40 ` no-reply
2017-08-17 3:35 ` Sam Bobroff
2017-08-21 9:10 ` Aravinda Prasad
2017-08-23 0:43 ` David Gibson
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=20170817015735.GD5509@umbus.fritz.box \
--to=david@gibson.dropbear.id.au \
--cc=aik@ozlabs.ru \
--cc=aravinda@linux.vnet.ibm.com \
--cc=benh@au1.ibm.com \
--cc=mahesh@linux.vnet.ibm.com \
--cc=paulus@samba.org \
--cc=qemu-devel@nongnu.org \
--cc=qemu-ppc@nongnu.org \
--cc=sam.bobroff@au1.ibm.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.