Re: [PATCH v16] qapi: introduce 'x-query-x86-cpuid' QMP command.

Vladimir Sementsov-Ogievskiy
2022-01-21T16:33:56Z

19.01.2022 17:37, Markus Armbruster wrote:
> Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> writes:
>
>> From: Valeriy Vdovin <valeriy.vdovin@virtuozzo.com>
>>
>> Introducing new QMP command 'query-x86-cpuid'. This command can be used to
>> get virtualized cpu model info generated by QEMU during VM initialization in
>> the form of cpuid representation.
>>
>> Diving into more details about virtual CPU generation: QEMU first parses '-cpu'
>> command line option. From there it takes the name of the model as the basis for
>> feature set of the new virtual CPU. After that it uses trailing '-cpu' options,
>> that state if additional cpu features should be present on the virtual CPU or
>> excluded from it (tokens '+'/'-' or '=on'/'=off').
>> After that QEMU checks if the host's cpu can actually support the derived
>> feature set and applies host limitations to it.
>> After this initialization procedure, virtual CPU has it's model and
>> vendor names, and a working feature set and is ready for identification
>> instructions such as CPUID.
>>
>> To learn exactly how virtual CPU is presented to the guest machine via CPUID
>> instruction, new QMP command can be used. By calling 'query-x86-cpuid'
>> command, one can get a full listing of all CPUID leaves with subleaves which are
>> supported by the initialized virtual CPU.
>>
>> Other than debug, the command is useful in cases when we would like to
>> utilize QEMU's virtual CPU initialization routines and put the retrieved
>> values into kernel CPUID overriding mechanics for more precise control
>> over how various processes perceive its underlying hardware with
>> container processes as a good example.
>>
>> The command is specific to x86. It is currenly only implemented for KVM acceleator.
>
> Please wrap your commit messages around column 70.
>
>>
>> Output format:
>> The output is a plain list of leaf/subleaf argument combinations, that
>> return 4 words in registers EAX, EBX, ECX, EDX.
>>
>> Use example:
>> qmp_request: {
>> "execute": "x-query-x86-cpuid"
>> }
>>
>> qmp_response: {
>> "return": [
>> {
>> "eax": 1073741825,
>> "edx": 77,
>> "in-eax": 1073741824,
>> "ecx": 1447775574,
>> "ebx": 1263359563
>> },
>> {
>> "eax": 16777339,
>> "edx": 0,
>> "in-eax": 1073741825,
>> "ecx": 0,
>> "ebx": 0
>> },
>> {
>> "eax": 13,
>> "edx": 1231384169,
>> "in-eax": 0,
>> "ecx": 1818588270,
>> "ebx": 1970169159
>> },
>> {
>> "eax": 198354,
>> "edx": 126614527,
>> "in-eax": 1,
>> "ecx": 2176328193,
>> "ebx": 2048
>> },
>> ....
>> {
>> "eax": 12328,
>> "edx": 0,
>> "in-eax": 2147483656,
>> "ecx": 0,
>> "ebx": 0
>> }
>> ]
>> }
>>
>> Signed-off-by: Valeriy Vdovin <valeriy.vdovin@virtuozzo.com>
>> Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
>
> This needs review from x86 CPU maintainers. Eduardo?
>
> [...]
>
>> diff --git a/qapi/machine-target.json b/qapi/machine-target.json
>> index f5ec4bc172..0ac575b1b9 100644
>> --- a/qapi/machine-target.json
>> +++ b/qapi/machine-target.json
>> @@ -341,3 +341,49 @@
>> 'TARGET_I386',
>> 'TARGET_S390X',
>> 'TARGET_MIPS' ] } }
>> +
>> +##
>> +# @CpuidEntry:
>> +#
>> +# A single entry of a CPUID response.
>> +#
>> +# One entry holds full set of information (leaf) returned to the guest
>> +# in response to it calling a CPUID instruction with eax, ecx used as
>> +# the arguments to that instruction. ecx is an optional argument as
>> +# not all of the leaves support it.
>> +#
>> +# @in-eax: CPUID argument in eax
>> +# @in-ecx: CPUID argument in ecx
>> +# @eax: CPUID result in eax
>> +# @ebx: CPUID result in ebx
>> +# @ecx: CPUID result in ecx
>> +# @edx: CPUID result in edx
>> +#
>> +# Since: 7.0
>> +##
>> +{ 'struct': 'CpuidEntry',
>> + 'data': { 'in-eax' : 'uint32',
>> + '*in-ecx' : 'uint32',
>> + 'eax' : 'uint32',
>> + 'ebx' : 'uint32',
>> + 'ecx' : 'uint32',
>> + 'edx' : 'uint32'
>> + },
>> + 'if': 'TARGET_I386' }
>> +
>> +##
>> +# @x-query-x86-cpuid:
>> +#
>> +# Returns raw data from the emulated CPUID table for the first VCPU.
>> +# The emulated CPUID table defines the response to the CPUID
>> +# instruction when executed by the guest operating system.
>> +#
>> +#
>> +# Returns: a list of CpuidEntry. Returns error when qemu is configured with
>> +# --disable-kvm flag or if qemu is run with any other accelerator than KVM.
>
> Long line, please wrap around column 70.
>
>> +#
>> +# Since: 7.0
>> +##
>> +{ 'command': 'x-query-x86-cpuid',
>> + 'returns': ['CpuidEntry'],
>> + 'if': 'TARGET_I386' }
>
> Needs feature 'unstable' now; see commit a3c45b3e62 'qapi: New special
> feature flag "unstable"' and also commit 57df0dff1a "qapi: Extend
> -compat to set policy for unstable interfaces". Incremental patch
> appended for your convenience.
>
>
> diff --git a/qapi/machine-target.json b/qapi/machine-target.json
> index 0ac575b1b9..049fa48a35 100644
> --- a/qapi/machine-target.json
> +++ b/qapi/machine-target.json
> @@ -378,6 +378,8 @@
> # The emulated CPUID table defines the response to the CPUID
> # instruction when executed by the guest operating system.
> #
> +# Features:
> +# @unstable: This command is experimental.
> #
> # Returns: a list of CpuidEntry. Returns error when qemu is configured with
> # --disable-kvm flag or if qemu is run with any other accelerator than KVM.
> @@ -386,4 +388,5 @@
> ##
> { 'command': 'x-query-x86-cpuid',
> 'returns': ['CpuidEntry'],
> - 'if': 'TARGET_I386' }
> + 'if': 'TARGET_I386',
> + 'features': [ 'unstable' ] }
>

Thanks! I'll resend for convenience.

--
Best regards,
Vladimir