[libvirt] [PATCH 6/6] qemu, inject-nmi: Implement the driver methods
Eric Blake
eblake at redhat.com
Fri Apr 15 18:13:50 UTC 2011
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 at redhat.com +1-801-349-2682
Libvirt virtualization library http://libvirt.org
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 619 bytes
Desc: OpenPGP digital signature
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20110415/5113c330/attachment-0001.sig>
More information about the libvir-list
mailing list