Commit 38a01e55 authored by Peter Maydell's avatar Peter Maydell
Browse files

Merge remote-tracking branch 'remotes/kvm/tags/for-upstream' into staging



Mostly bugfixes + Alexey's interface-based implementation
of the NMI monitor command.

# gpg: Signature made Thu 28 Aug 2014 15:07:22 BST using RSA key ID 9B4D86F2
# gpg: Good signature from "Paolo Bonzini <pbonzini@redhat.com>"
# gpg:                 aka "Paolo Bonzini <bonzini@gnu.org>"

* remotes/kvm/tags/for-upstream:
  mc146818rtc: reinitialize irq_reinject_on_ack_count on reset
  target-i386: Add "tsc_adjust" CPU feature name
  target-i386: Add "mpx" CPU feature name
  vl: process -object after other backend options
  checkpatch.pl: adjust typedef definition to QEMU coding style
  x86: Clear MTRRs on vCPU reset
  x86: kvm: Add MTRR support for kvm_get|put_msrs()
  x86: Use common variable range MTRR counts
  target-i386: Don't forbid NX bit on PAE PDEs and PTEs
  spapr: Add support for new NMI interface
  s390x: Migrate to new NMI interface
  s390x: Convert QEMUMachine to MachineClass
  cpus: Define callback for QEMU "nmi" command
  kvm: run cpu state synchronization on target vcpu thread

Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
parents 795c050e 172dbc52
Loading
Loading
Loading
Loading
+2 −15
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@
#include "qemu/bitmap.h"
#include "qemu/seqlock.h"
#include "qapi-event.h"
#include "hw/nmi.h"

#ifndef _WIN32
#include "qemu/compatfd.h"
@@ -1536,22 +1537,8 @@ void qmp_inject_nmi(Error **errp)
            apic_deliver_nmi(cpu->apic_state);
        }
    }
#elif defined(TARGET_S390X)
    CPUState *cs;
    S390CPU *cpu;

    CPU_FOREACH(cs) {
        cpu = S390_CPU(cs);
        if (cpu->env.cpu_num == monitor_get_cpu_index()) {
            if (s390_cpu_restart(S390_CPU(cs)) == -1) {
                error_set(errp, QERR_UNSUPPORTED);
                return;
            }
            break;
        }
    }
#else
    error_set(errp, QERR_UNSUPPORTED);
    nmi_monitor_handle(monitor_get_cpu_index(), errp);
#endif
}

+2 −4
Original line number Diff line number Diff line
@@ -832,19 +832,17 @@ The values that can be specified here depend on the machine type, but are
the same that can be specified in the @code{-boot} command line option.
ETEXI

#if defined(TARGET_I386) || defined(TARGET_S390X)
    {
        .name       = "nmi",
        .args_type  = "",
        .params     = "",
        .help       = "inject an NMI on all guest's CPUs",
        .help       = "inject an NMI",
        .mhandler.cmd = hmp_inject_nmi,
    },
#endif
STEXI
@item nmi @var{cpu}
@findex nmi
Inject an NMI (x86) or RESTART (s390x) on the given CPU.
Inject an NMI on the default CPU (x86/s390) or all CPUs (ppc64).

ETEXI

+1 −0
Original line number Diff line number Diff line
@@ -4,6 +4,7 @@ common-obj-y += fw-path-provider.o
# irq.o needed for qdev GPIO handling:
common-obj-y += irq.o
common-obj-y += hotplug.o
common-obj-y += nmi.o

common-obj-$(CONFIG_EMPTY_SLOT) += empty_slot.o
common-obj-$(CONFIG_XILINX_AXI) += stream.o

hw/core/nmi.c

0 → 100644
+84 −0
Original line number Diff line number Diff line
/*
 *  NMI monitor handler class and helpers.
 *
 *  Copyright IBM Corp., 2014
 *
 *  Author: Alexey Kardashevskiy <aik@ozlabs.ru>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License,
 *  or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, see <http://www.gnu.org/licenses/>.
 */

#include "hw/nmi.h"
#include "qapi/qmp/qerror.h"

struct do_nmi_s {
    int cpu_index;
    Error *errp;
    bool handled;
};

static void nmi_children(Object *o, struct do_nmi_s *ns);

static int do_nmi(Object *o, void *opaque)
{
    struct do_nmi_s *ns = opaque;
    NMIState *n = (NMIState *) object_dynamic_cast(o, TYPE_NMI);

    if (n) {
        NMIClass *nc = NMI_GET_CLASS(n);

        ns->handled = true;
        nc->nmi_monitor_handler(n, ns->cpu_index, &ns->errp);
        if (ns->errp) {
            return -1;
        }
    }
    nmi_children(o, ns);

    return 0;
}

static void nmi_children(Object *o, struct do_nmi_s *ns)
{
    object_child_foreach(o, do_nmi, ns);
}

void nmi_monitor_handle(int cpu_index, Error **errp)
{
    struct do_nmi_s ns = {
        .cpu_index = cpu_index,
        .errp = NULL,
        .handled = false
    };

    nmi_children(object_get_root(), &ns);
    if (ns.handled) {
        error_propagate(errp, ns.errp);
    } else {
        error_set(errp, QERR_UNSUPPORTED);
    }
}

static const TypeInfo nmi_info = {
    .name          = TYPE_NMI,
    .parent        = TYPE_INTERFACE,
    .class_size    = sizeof(NMIClass),
};

static void nmi_register_types(void)
{
    type_register_static(&nmi_info);
}

type_init(nmi_register_types)
+21 −0
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@
#include "qemu/config-file.h"
#include "qemu/error-report.h"
#include "trace.h"
#include "hw/nmi.h"

#include <libfdt.h>

@@ -1576,10 +1577,28 @@ static void spapr_machine_initfn(Object *obj)
                            spapr_get_kvm_type, spapr_set_kvm_type, NULL);
}

static void ppc_cpu_do_nmi_on_cpu(void *arg)
{
    CPUState *cs = arg;

    cpu_synchronize_state(cs);
    ppc_cpu_do_system_reset(cs);
}

static void spapr_nmi(NMIState *n, int cpu_index, Error **errp)
{
    CPUState *cs;

    CPU_FOREACH(cs) {
        async_run_on_cpu(cs, ppc_cpu_do_nmi_on_cpu, cs);
    }
}

static void spapr_machine_class_init(ObjectClass *oc, void *data)
{
    MachineClass *mc = MACHINE_CLASS(oc);
    FWPathProviderClass *fwc = FW_PATH_PROVIDER_CLASS(oc);
    NMIClass *nc = NMI_CLASS(oc);

    mc->name = "pseries";
    mc->desc = "pSeries Logical Partition (PAPR compliant)";
@@ -1593,6 +1612,7 @@ static void spapr_machine_class_init(ObjectClass *oc, void *data)
    mc->kvm_type = spapr_kvm_type;

    fwc->get_dev_path = spapr_get_fw_dev_path;
    nc->nmi_monitor_handler = spapr_nmi;
}

static const TypeInfo spapr_machine_info = {
@@ -1603,6 +1623,7 @@ static const TypeInfo spapr_machine_info = {
    .class_init    = spapr_machine_class_init,
    .interfaces = (InterfaceInfo[]) {
        { TYPE_FW_PATH_PROVIDER },
        { TYPE_NMI },
        { }
    },
};
Loading