[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <54994B7B.20309@citrix.com>
Date: Tue, 23 Dec 2014 11:01:15 +0000
From: David Vrabel <david.vrabel@...rix.com>
To: Jan Beulich <JBeulich@...e.com>,
David Vrabel <david.vrabel@...rix.com>,
Boris Ostrovsky <boris.ostrovsky@...cle.com>,
Konrad Rzeszutek Wilk <konrad.wilk@...cle.com>
CC: xen-devel <xen-devel@...ts.xenproject.org>,
<linux-kernel@...r.kernel.org>
Subject: Re: [Xen-devel] xen/x86: properly retrieve NMI reason
On 19/12/14 16:16, Jan Beulich wrote:
> Using the native code here can't work properly, as the hypervisor would
> normally have cleared the two reason bits by the time Dom0 gets to see
> the NMI (if passed to it at all). There's a shared info field for this,
> and there's an existing hook to use - just fit the two together. Note
> that the hook can (and should) be used irrespective of whether being in
> Dom0, as accessing port 0x61 in a DomU would be even worse, while the
> shared info field would just hold zero all the time.
What's the user visible impact of this fix?
David
>
> Signed-off-by: Jan Beulich <jbeulich@...e.com>
> ---
> arch/x86/xen/enlighten.c | 22 +++++++++++++++++-
> include/xen/interface/nmi.h | 52 ++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 73 insertions(+), 1 deletion(-)
>
> --- 3.18/arch/x86/xen/enlighten.c
> +++ 3.18-xen-x86-NMI-reason/arch/x86/xen/enlighten.c
> @@ -40,6 +40,7 @@
> #include <xen/interface/physdev.h>
> #include <xen/interface/vcpu.h>
> #include <xen/interface/memory.h>
> +#include <xen/interface/nmi.h>
> #include <xen/interface/xen-mca.h>
> #include <xen/features.h>
> #include <xen/page.h>
> @@ -66,6 +67,7 @@
> #include <asm/reboot.h>
> #include <asm/stackprotector.h>
> #include <asm/hypervisor.h>
> +#include <asm/mach_traps.h>
> #include <asm/mwait.h>
> #include <asm/pci_x86.h>
> #include <asm/pat.h>
> @@ -1357,6 +1359,21 @@ static const struct machine_ops xen_mach
> .emergency_restart = xen_emergency_restart,
> };
>
> +static unsigned char xen_get_nmi_reason(void)
> +{
> + unsigned char reason = 0;
> +
> + /* Construct a value which looks like it came from port 0x61. */
> + if (test_bit(_XEN_NMIREASON_io_error,
> + &HYPERVISOR_shared_info->arch.nmi_reason))
> + reason |= NMI_REASON_IOCHK;
> + if (test_bit(_XEN_NMIREASON_pci_serr,
> + &HYPERVISOR_shared_info->arch.nmi_reason))
> + reason |= NMI_REASON_SERR;
> +
> + return reason;
> +}
> +
> static void __init xen_boot_params_init_edd(void)
> {
> #if IS_ENABLED(CONFIG_EDD)
> @@ -1541,9 +1558,12 @@ asmlinkage __visible void __init xen_sta
> pv_info = xen_info;
> pv_init_ops = xen_init_ops;
> pv_apic_ops = xen_apic_ops;
> - if (!xen_pvh_domain())
> + if (!xen_pvh_domain()) {
> pv_cpu_ops = xen_cpu_ops;
>
> + x86_platform.get_nmi_reason = xen_get_nmi_reason;
> + }
> +
> if (xen_feature(XENFEAT_auto_translated_physmap))
> x86_init.resources.memory_setup = xen_auto_xlated_memory_setup;
> else
> --- /usr/local/src/linux-3.18/include/xen/interface/nmi.h 1970-01-01 01:00:00.000000000 +0100
> +++ 3.18-xen-x86-NMI-reason/include/xen/interface/nmi.h
> @@ -0,0 +1,52 @@
> +/******************************************************************************
> + * nmi.h
> + *
> + * NMI callback registration and reason codes.
> + *
> + * Copyright (c) 2005, Keir Fraser <keir@...source.com>
> + */
> +
> +#ifndef __XEN_PUBLIC_NMI_H__
> +#define __XEN_PUBLIC_NMI_H__
> +
> +#include <xen/interface/xen.h>
> +
> +/*
> + * NMI reason codes:
> + * Currently these are x86-specific, stored in arch_shared_info.nmi_reason.
> + */
> + /* I/O-check error reported via ISA port 0x61, bit 6. */
> +#define _XEN_NMIREASON_io_error 0
> +#define XEN_NMIREASON_io_error (1UL << _XEN_NMIREASON_io_error)
> + /* PCI SERR reported via ISA port 0x61, bit 7. */
> +#define _XEN_NMIREASON_pci_serr 1
> +#define XEN_NMIREASON_pci_serr (1UL << _XEN_NMIREASON_pci_serr)
> + /* Unknown hardware-generated NMI. */
> +#define _XEN_NMIREASON_unknown 2
> +#define XEN_NMIREASON_unknown (1UL << _XEN_NMIREASON_unknown)
> +
> +/*
> + * long nmi_op(unsigned int cmd, void *arg)
> + * NB. All ops return zero on success, else a negative error code.
> + */
> +
> +/*
> + * Register NMI callback for this (calling) VCPU. Currently this only makes
> + * sense for domain 0, vcpu 0. All other callers will be returned EINVAL.
> + * arg == pointer to xennmi_callback structure.
> + */
> +#define XENNMI_register_callback 0
> +struct xennmi_callback {
> + unsigned long handler_address;
> + unsigned long pad;
> +};
> +typedef struct xennmi_callback xennmi_callback_t;
> +DEFINE_XEN_GUEST_HANDLE(xennmi_callback_t);
> +
> +/*
> + * Deregister NMI callback for this (calling) VCPU.
> + * arg == NULL.
> + */
> +#define XENNMI_unregister_callback 1
> +
> +#endif /* __XEN_PUBLIC_NMI_H__ */
>
>
>
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@...ts.xen.org
> http://lists.xen.org/xen-devel
>
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists