[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH v10 29/30] cpu: Convert CpuInfo into flat union
From: |
Markus Armbruster |
Subject: |
Re: [Qemu-devel] [PATCH v10 29/30] cpu: Convert CpuInfo into flat union |
Date: |
Mon, 09 Nov 2015 16:22:50 +0100 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/24.5 (gnu/linux) |
Eric Blake <address@hidden> writes:
> When qapi type CpuInfo was originally created for 0.14, we had
> no notion of a flat union, and instead just listed a bunch of
> optional fields with documentation about the mutually-exclusive
> choice of which instruction pointer field(s) would be provided
> for a given architecture. But now that we have flat unions and
> introspection, it is better to segregate off which fields will
> be provided according to the actual architecture. With this in
> place, we no longer need the fields to be optional, because the
> choice of the discriminator serves that role.
>
> This has an additional benefit: the old all-in-one struct was
> the only place in the code base that had a case-sensitive
> naming of members 'pc' vs. 'PC'. Separating these spellings
> into different branches of the flat union will allow us to add
> restrictions against future case-insensitive collisions, and
> make it possible for a future qemu to decide whether to enable
> case-insensitive QMP.
>
> Signed-off-by: Eric Blake <address@hidden>
>
> ---
> v10: new patch
> ---
> cpus.c | 31 ++++++++------
> hmp.c | 30 +++++++++-----
> qapi-schema.json | 120
> ++++++++++++++++++++++++++++++++++++++++++++++---------
> 3 files changed, 139 insertions(+), 42 deletions(-)
>
> diff --git a/cpus.c b/cpus.c
> index c6a5d0e..1c8078d 100644
> --- a/cpus.c
> +++ b/cpus.c
> @@ -1526,22 +1526,29 @@ CpuInfoList *qmp_query_cpus(Error **errp)
> info->value->qom_path = object_get_canonical_path(OBJECT(cpu));
> info->value->thread_id = cpu->thread_id;
> #if defined(TARGET_I386)
> - info->value->has_pc = true;
> - info->value->pc = env->eip + env->segs[R_CS].base;
> + info->value->arch = CPU_INFO_ARCH_X86;
> + info->value->u.x86 = g_new0(CpuInfoX86, 1);
> + info->value->u.x86->pc = env->eip + env->segs[R_CS].base;
> #elif defined(TARGET_PPC)
> - info->value->has_nip = true;
> - info->value->nip = env->nip;
> + info->value->arch = CPU_INFO_ARCH_PPC;
> + info->value->u.ppc = g_new0(CpuInfoPpc, 1);
> + info->value->u.ppc->nip = env->nip;
> #elif defined(TARGET_SPARC)
> - info->value->has_pc = true;
> - info->value->pc = env->pc;
> - info->value->has_npc = true;
> - info->value->npc = env->npc;
> + info->value->arch = CPU_INFO_ARCH_SPARC;
> + info->value->u.sparc = g_new0(CpuInfoSPARC, 1);
> + info->value->u.sparc->pc = env->pc;
> + info->value->u.sparc->npc = env->npc;
> #elif defined(TARGET_MIPS)
> - info->value->has_PC = true;
> - info->value->PC = env->active_tc.PC;
> + info->value->arch = CPU_INFO_ARCH_MIPS;
> + info->value->u.mips = g_new0(CpuInfoMips, 1);
> + info->value->u.mips->PC = env->active_tc.PC;
> #elif defined(TARGET_TRICORE)
> - info->value->has_PC = true;
> - info->value->PC = env->PC;
> + info->value->arch = CPU_INFO_ARCH_TRICORE;
> + info->value->u.tricore = g_new0(CpuInfoTricore, 1);
> + info->value->u.tricore->PC = env->PC;
> +#else
> + info->value->arch = CPU_INFO_ARCH_OTHER;
> + info->value->u.other = g_new0(CpuInfoOther, 1);
> #endif
>
> /* XXX: waiting for the qapi to support GSList */
> diff --git a/hmp.c b/hmp.c
> index a15d00c..1307016 100644
> --- a/hmp.c
> +++ b/hmp.c
> @@ -310,17 +310,25 @@ void hmp_info_cpus(Monitor *mon, const QDict *qdict)
>
> monitor_printf(mon, "%c CPU #%" PRId64 ":", active, cpu->value->CPU);
>
> - if (cpu->value->has_pc) {
> - monitor_printf(mon, " pc=0x%016" PRIx64, cpu->value->pc);
> - }
> - if (cpu->value->has_nip) {
> - monitor_printf(mon, " nip=0x%016" PRIx64, cpu->value->nip);
> - }
> - if (cpu->value->has_npc) {
> - monitor_printf(mon, " npc=0x%016" PRIx64, cpu->value->npc);
> - }
> - if (cpu->value->has_PC) {
> - monitor_printf(mon, " PC=0x%016" PRIx64, cpu->value->PC);
> + switch (cpu->value->arch) {
> + case CPU_INFO_ARCH_X86:
> + monitor_printf(mon, " pc=0x%016" PRIx64, cpu->value->u.x86->pc);
> + break;
> + case CPU_INFO_ARCH_PPC:
> + monitor_printf(mon, " nip=0x%016" PRIx64,
> cpu->value->u.ppc->nip);
> + break;
> + case CPU_INFO_ARCH_SPARC:
> + monitor_printf(mon, " pc=0x%016" PRIx64,
> cpu->value->u.sparc->pc);
> + monitor_printf(mon, " npc=0x%016" PRIx64,
> cpu->value->u.sparc->npc);
> + break;
> + case CPU_INFO_ARCH_MIPS:
> + monitor_printf(mon, " PC=0x%016" PRIx64, cpu->value->u.mips->PC);
> + break;
> + case CPU_INFO_ARCH_TRICORE:
> + monitor_printf(mon, " PC=0x%016" PRIx64,
> cpu->value->u.tricore->PC);
> + break;
> + default:
> + break;
> }
>
> if (cpu->value->halted) {
> diff --git a/qapi-schema.json b/qapi-schema.json
> index 702b7b5..dd497ea 100644
> --- a/qapi-schema.json
> +++ b/qapi-schema.json
> @@ -728,43 +728,125 @@
> { 'command': 'query-mice', 'returns': ['MouseInfo'] }
>
> ##
> -# @CpuInfo:
> +# @CpuInfoArch:
> #
> -# Information about a virtual CPU
> +# An enumeration of cpu types that enable additional information during
> +# @query-cpus.
> +#
> +# Since: 2.5
> +##
> +{ 'enum': 'CpuInfoArch',
> + 'data': ['x86', 'sparc', 'ppc', 'mips', 'tricore', 'other' ] }
> +
> +##
> +# @CpuInfoBase:
> +#
> +# Common information about a virtual CPU
> #
> # @CPU: the index of the virtual CPU
> #
> -# @current: this only exists for backwards compatible and should be ignored
> +# @current: this only exists for backwards compatibility and should be
> ignored
> #
> # @halted: true if the virtual CPU is in the halt state. Halt usually refers
> # to a processor specific low power mode.
> #
> # @qom_path: path to the CPU object in the QOM tree (since 2.4)
> #
> -# @pc: #optional If the target is i386 or x86_64, this is the 64-bit
> instruction
> -# pointer.
> -# If the target is Sparc, this is the PC component of the
> -# instruction pointer.
> -#
> -# @nip: #optional If the target is PPC, the instruction pointer
> -#
> -# @npc: #optional If the target is Sparc, the NPC component of the
> instruction
> -# pointer
> -#
> -# @PC: #optional If the target is MIPS, the instruction pointer
> -#
> # @thread_id: ID of the underlying host thread
> #
> +# @arch: architecture of the cpu, which determines which additional fields
> +# will be listed (since 2.5)
> +#
> # Since: 0.14.0
> #
> # Notes: @halted is a transient state that changes frequently. By the time
> the
> # data is sent to the client, the guest may no longer be halted.
> ##
> -{ 'struct': 'CpuInfo',
> +{ 'struct': 'CpuInfoBase',
> 'data': {'CPU': 'int', 'current': 'bool', 'halted': 'bool',
> - 'qom_path': 'str',
> - '*pc': 'int', '*nip': 'int', '*npc': 'int', '*PC': 'int',
> - 'thread_id': 'int'} }
> + 'qom_path': 'str', 'thread_id': 'int', 'arch': 'CpuInfoArch' } }
> +
> +##
> +# @CpuInfo:
> +#
> +# Information about a virtual CPU
> +#
> +# Since: 0.14.0
> +##
> +{ 'union': 'CpuInfo', 'base': 'CpuInfoBase', 'discriminator': 'arch',
> + 'data': { 'x86': 'CpuInfoX86',
> + 'sparc': 'CpuInfoSparc',
> + 'ppc': 'CpuInfoPpc',
> + 'mips': 'CpuInfoMips',
> + 'tricore': 'CpuInfoTricore',
> + 'other': 'CpuInfoOther' } }
> +
> +##
> +# @CpuInfoX86:
> +#
> +# Additional information about a virtual i386 or x86_64 CPU
> +#
> +# @pc: the 64-bit instruction pointer
> +#
> +# Since 2.5
> +##
> +{ 'struct': 'CpuInfoX86', 'data': { 'pc': 'int' } }
> +
> +##
> +# @CpuInfoSparc:
> +#
> +# Additional information about a virtual Sparc CPU
> +#
> +# @pc: the PC component of the instruction pointer
> +#
> +# @npc: the NPC component of the instruction pointer
> +#
> +# Since 2.5
> +##
> +{ 'struct': 'CpuInfoSparc', 'data': { 'pc': 'int', 'npc': 'int' } }
> +
> +##
> +# @CpuInfoPpc:
> +#
> +# Additional information about a virtual PPC CPU
> +#
> +# @nip: the instruction pointer
> +#
> +# Since 2.5
> +##
> +{ 'struct': 'CpuInfoPpc', 'data': { 'nip': 'int' } }
> +
> +##
> +# @CpuInfoMips:
> +#
> +# Additional information about a virtual MIPS CPU
> +#
> +# @PC: the instruction pointer
> +#
> +# Since 2.5
> +##
> +{ 'struct': 'CpuInfoMips', 'data': { 'PC': 'int' } }
> +
> +##
> +# @CpuInfoMips:
> +#
> +# Additional information about a virtual Tricore CPU
> +#
> +# @PC: the instruction pointer
> +#
> +# Since 2.5
> +##
> +{ 'struct': 'CpuInfoTricore', 'data': { 'PC': 'int' } }
> +
> +##
> +# @CpuInfoOther:
> +#
> +# No additional information is available about the virtual CPU
> +#
> +# Since 2.5
> +#
> +##
> +{ 'struct': 'CpuInfoOther', 'data': { } }
>
> ##
> # @query-cpus:
CpuInfo is only used as return type of query-cpus.
If I understand the change correctly, the value of query-cpus is not
changed at all. Its introspection, however, is.
Do we need this to make 2.5?
Any other messy optionals that should really be (flat) unions?
- Re: [Qemu-devel] [PATCH v10 27/30] qapi: Track owner of each object member, (continued)
[Qemu-devel] [PATCH v10 26/30] qapi: Remove outdated tests related to QMP/branch collisions, Eric Blake, 2015/11/06
[Qemu-devel] [PATCH v10 20/30] qapi: Eliminate QAPISchemaObjectType.check() variable members, Eric Blake, 2015/11/06
Re: [Qemu-devel] [PATCH v10 00/30] qapi member collision (post-introspection cleanups, subset C'), Markus Armbruster, 2015/11/06