On 04/12/2011 11:01 PM, Lai Jiangshan wrote:
+++ b/src/qemu/qemu_driver.c
@@ -1701,6 +1701,48 @@ static int qemudDomainSetMaxMemory(virDomainPtr dom, unsigned long
memory)
return qemudDomainSetMemoryFlags(dom, memory, VIR_DOMAIN_MEM_MAXIMUM);
}
+static int qemuDomainInjectNMI(virDomainPtr domain, unsigned int flags)
+{
+ struct qemud_driver *driver = domain->conn->privateData;
+ virDomainObjPtr vm = NULL;
+ int ret = -1;
+ qemuDomainObjPrivatePtr priv;
+
Right here, you should have a virCheckFlags(0, -1) to enforce that we
don't honor any flags for now. At which point, you don't need to pass
flags on down to the monitor calls.
+++ b/src/qemu/qemu_monitor_json.c
@@ -2513,3 +2513,32 @@ cleanup:
return ret;
}
+
+int qemuMonitorJSONInjectNMI(qemuMonitorPtr mon, unsigned int flags ATTRIBUTE_UNUSED)
+{
Since neither monitor needed flags this low, you don't have to propogate
it any further than qemu_driver.c's virCheckFlags().
+ int ret;
+ virJSONValuePtr cmd;
+ virJSONValuePtr reply = NULL;
+
+ /*
+ * FIXME: qmp nmi is not supported until qemu-0.16.0,
+ * use human-monitor-command instead temporary.
+ *
+ * FIXME: qemu's nmi command just injects NMI to a specified CPU,
+ * use "nmi 0" instead temporary.
+ */
+ cmd = qemuMonitorJSONMakeCommand("human-monitor-command",
+ "s:command-line", "nmi 0",
+ NULL);
We've already got a preferred form for issuing HMP commands from JSON.
Rather than building up human-monitor-command manually, you should
instead be using qemuMonitorTextInjectNMI; for example, see how
qemuMonitorJSONDriveDel falls back to hmp. This also covers the case of
a qemu binary that has JSON but not hmp giving a more useful error message.
+++ b/src/qemu/qemu_monitor_text.c
@@ -2628,3 +2628,23 @@ int qemuMonitorTextArbitraryCommand(qemuMonitorPtr mon, const char
*cmd,
return ret;
}
+
+int qemuMonitorTextInjectNMI(qemuMonitorPtr mon, unsigned int flags ATTRIBUTE_UNUSED)
+{
+ const char *cmd = "nmi 0";
+ char *reply = NULL;
+
+ /*
+ * FIXME: qemu's nmi command just injects NMI to a specified CPU,
+ * use "nmi 0" instead temporary.
+ */
This bothers me. Is it possible to inject NMI to a particular CPU in
bare-metal hardware? If so, then we ought to support that in the API.
I know what Dan said:
>> +int virDomainSendEventNMI(virDomainPtr domain, unsigned int
vcpu)
>
> Your proposal to qemu-devel to add inject-nmi for QMP does not
> include any CPU index parameter anymore. Instead it will automatically
> inject the NMI to all present CPUs. This libvirt API would appear to
> be incompatible with that QMP design. For Xen, it appears the API
> also does not allow a CPU index to be given - it just injects to the
> first CPU AFAICT.
>
> So do we really need to have a 'unsigned int vcpu' parameter in the
> libvirt API, or can we just leave it out and always inject to
> CPU==0 for HMP ?
>
> eg simplify to
>
> int virDomainSendNMI(virDomainPtr domain)
but if there's ever any possibility that qemu might learn how to direct
an NMI to a particular vcpu, I wonder if we should instead have:
enum {
VIR_DOMAIN_INJECT_NMI_FIRST = 1,
VIR_DOMAIN_INJECT_NMI_ALL = 2,
}
/**
* virDomainInjectNMI:
* @domain: pointer to domain object, or NULL for Domain0
* @vcpu: which vcpu to send the NMI to
* @flags: the flags for controlling behaviours
*
* Send NMI to the guest. If @flags contains
* VIR_DOMAIN_INJECT_NMI_FIRST or VIR_DOMAIN_INJECT_NMI_ALL,
* then @vcpu is ignored, and the NMI is sent to the first
* possible vcpu or to all vcpus, respectively. Otherwise,
* the NMI is sent to the specified vcpu; it is an error if
* @vcpu does not correspond to a currently online processor.
*
* Not all hypervisors support fine-tuned control over which
* vcpu(s) can be targetted, and might succeed only for a
* particular value of @flags.
*
* Returns 0 in case of success, -1 in case of failure.
*/
int virDomainInjectNMI(virDomainPtr domain, unsigned int vcpu,
unsigned int flags);
Then xen would be hardcoded to require flags==_FIRST (and always ignore
vcpu), whereas qemu can honor a particular vcpu.
Or is the first vcpu always 0? That is, are there any hypervisors that
let you offline vcpu 0 while leaving vcpu1 up, so that FIRST would imply
1? Maybe we don't need a flag for FIRST, but document that vcpu is
ignored if ALL is passed, and then make xen error out if ALL is passed
or if vcpu != 0.
That said, I haven't looked at the proposed qemu side of the patches for
how the monitor command for nmi will be implemented in the first place,
and until that is in a formal qemu release, we may still need to be a
bit flexible here on the libvirt side. Do any other hypervisors allow
NMI injection, and with what semantics?
--
Eric Blake eblake(a)redhat.com +1-801-349-2682
Libvirt virtualization library
http://libvirt.org