public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
From: Markus Armbruster <armbru@redhat.com>
To: "Daniel P. Berrangé" <berrange@redhat.com>
Cc: Michael Roth <michael.roth@amd.com>,
	 qemu-devel@nongnu.org, kvm@vger.kernel.org,
	 Tom Lendacky <thomas.lendacky@amd.com>,
	 Paolo Bonzini <pbonzini@redhat.com>,
	 Pankaj Gupta <pankaj.gupta@amd.com>,
	Xiaoyao Li <xiaoyao.li@intel.com>,
	 Isaku Yamahata <isaku.yamahata@linux.intel.com>
Subject: Re: [PATCH v3 21/49] i386/sev: Introduce "sev-common" type to encapsulate common SEV state
Date: Wed, 27 Mar 2024 16:22:06 +0100	[thread overview]
Message-ID: <87h6gritsx.fsf@pond.sub.org> (raw)
In-Reply-To: <ZfrMDYk-gSQF04gQ@redhat.com> ("Daniel P. Berrangé"'s message of "Wed, 20 Mar 2024 11:44:13 +0000")

Daniel P. Berrangé <berrange@redhat.com> writes:

> On Wed, Mar 20, 2024 at 03:39:17AM -0500, Michael Roth wrote:
>> Currently all SEV/SEV-ES functionality is managed through a single
>> 'sev-guest' QOM type. With upcoming support for SEV-SNP, taking this
>> same approach won't work well since some of the properties/state
>> managed by 'sev-guest' is not applicable to SEV-SNP, which will instead
>> rely on a new QOM type with its own set of properties/state.
>> 
>> To prepare for this, this patch moves common state into an abstract
>> 'sev-common' parent type to encapsulate properties/state that are
>> common to both SEV/SEV-ES and SEV-SNP, leaving only SEV/SEV-ES-specific
>> properties/state in the current 'sev-guest' type. This should not
>> affect current behavior or command-line options.
>> 
>> As part of this patch, some related changes are also made:
>> 
>>   - a static 'sev_guest' variable is currently used to keep track of
>>     the 'sev-guest' instance. SEV-SNP would similarly introduce an
>>     'sev_snp_guest' static variable. But these instances are now
>>     available via qdev_get_machine()->cgs, so switch to using that
>>     instead and drop the static variable.
>> 
>>   - 'sev_guest' is currently used as the name for the static variable
>>     holding a pointer to the 'sev-guest' instance. Re-purpose the name
>>     as a local variable referring the 'sev-guest' instance, and use
>>     that consistently throughout the code so it can be easily
>>     distinguished from sev-common/sev-snp-guest instances.
>> 
>>   - 'sev' is generally used as the name for local variables holding a
>>     pointer to the 'sev-guest' instance. In cases where that now points
>>     to common state, use the name 'sev_common'; in cases where that now
>>     points to state specific to 'sev-guest' instance, use the name
>>     'sev_guest'
>> 
>> Signed-off-by: Michael Roth <michael.roth@amd.com>
>> ---
>>  qapi/qom.json     |  32 ++--
>>  target/i386/sev.c | 457 ++++++++++++++++++++++++++--------------------
>>  target/i386/sev.h |   3 +
>>  3 files changed, 281 insertions(+), 211 deletions(-)
>> 
>> diff --git a/qapi/qom.json b/qapi/qom.json
>> index baae3a183f..66b5781ca6 100644
>> --- a/qapi/qom.json
>> +++ b/qapi/qom.json
>> @@ -875,12 +875,29 @@
>>    'data': { '*filename': 'str' } }
>>  
>>  ##
>> -# @SevGuestProperties:
>> +# @SevCommonProperties:
>>  #
>> -# Properties for sev-guest objects.
>> +# Properties common to objects that are derivatives of sev-common.
>>  #
>>  # @sev-device: SEV device to use (default: "/dev/sev")
>>  #
>> +# @cbitpos: C-bit location in page table entry (default: 0)
>> +#
>> +# @reduced-phys-bits: number of bits in physical addresses that become
>> +#     unavailable when SEV is enabled
>> +#
>> +# Since: 2.12
>
> Not quite sure what we've done in this scenario before.
> It feels wierd to use '2.12' for the new base type, even
> though in effect the properties all existed since 2.12 in
> the sub-class.
>
> Perhaps 'Since: 9.1' for the type, but 'Since: 2.12' for the
> properties, along with an explanatory comment about stuff
> moving into the new base type ?
>
> Markus, opinions ?

The confusion is due to us documenting the schema instead of the
external interface defined by it.  Let me explain.

The external interface is commands and their arguments, ignoring
results, errors and events for brevity's sake.

We use types to define the arguments.  How exactly we use types is not
part of the interface.  This permits refactorings.  However, since the
documentation is attached to the types, refactorings can easily mess it
up.

I'd like to demonstrate this for a simpler command first, then return to
object-add.

Consider nbd-server-add.  It is documented to be since 1.3.

From now on, I'm abbreviating "documented to be since X.Y" to "since
X.Y".

Its arguments are the members of struct NbdServerAddOptions.

NbdServerAddOptions is since 5.0.  Its base BlockExportOptionsNbdBase is
since 5.2.

BlockExportOptionsNbdBase member @name is since 2.12, and @description
is since 5.0.

NbdServerAddOptions member @bitmap is since 4.0.  Members @device and
@writable have no "since" documented, so they inherit it from the
struct, i.e. 5.0.

So, it looks like the command is since 1.3, argument @name since 2.12,
@bitmap since 4.0, @description, @device, and @writable since 5.0.

Wrong!  Arguments @device and @writable have always been there,
i.e. since 1.3.  We ended up with documentation incorrectly claiming 5.0
via several refactorings.

Initially, the command arguments were defined right with the command.
They simply inherited the command's since 1.3.

Commit c62d24e906e (blockdev-nbd: Boxed argument type for
nbd-server-add) moved them to a struct type BlockExportNbd.  The new
struct type was since 5.0.  Newer arguments retained their "since" tags,
but the initial arguments @device and @writable remained without one.
Their documented "since" changed from 1.3 to 5.0.

Aside: the new struct was then used as a branch of union BlockExport,
which was incorrectly documented to be since 4.2.

Messing up "since" when factoring out arguments into a new type was
avoidable: either lie and claim the new type is as old as its members,
or add suitable since tags to its members.

Having a struct with members older than itself looks weird.  Of course,
when a struct came to be is *immaterial*.  How exactly we assemble the
arguments from types is not part of the interface.  We could omit
"since" for the struct, and then require it for all members.  We don't,
because having to think (and then argue!) whether we want a "since" or
not would be a waste of mental capacity.

Here's another refactoring where that may not be possible.  Say you
discover two structs share several members.  You decide to factor them
out into a common base type.  Won't affect the external interface.  But
what if one of these common members has conflicting "since"?  Either we
refrain from the refactoring, or we resort to something like "since
X1.Y1 when used for USER1, since X1.Y2 when used for USER2".  Which
*sucks* as external interface documentation.

Aside: documentation text could clash similarly.  Same code, different
meaning.

I've come to the conclusion that manually recording "since" in the
documentation is dumb.  One, because we mess it up.  Two, because not
messing it up involves either lies or oddities, or too much thought.
Three, because keeping it correct can interfere with refactorings.

Some time ago, Michael Tsirkin suggested to generate "since" information
automatically.  I like the idea.  We'd have to record the external
interface at release time.  To fully replace existing "since" tags, we'd
have to record for old versions, too.  I'd expect this to fix quite a
few doc bugs.

I hope "The confusion is due to us documenting the schema instead of the
external interface defined by it" is now more clear.  The external
interface is derived from the types.  How exactly we construct it from
types is invisible at the interface.  But since we document the
interface by documenting the types, the structure of our interface
documentation mirrors our use of types.  We succeed at shielding the
interface from how we use types, but we fail to shield the
documentation.

Back to your problem at hand.  The external interface is command
object-add.  The command is since 2.0.

It has common arguments and variant arguments depending on the value of
common argument @type.  We specify all that via union ObjectOptions, and
the variant arguments for @type value "sev-guest" via struct
SevGuestProperties.

Union ObjectOptions is since 6.0, but that's immaterial; the type isn't
part of the external interface, only its members are.

Its members are the common arguments.  Since they don't have their own
"since" tag, they inherit it from ObjectOptions, i.e. since 6.0.  That's
simply wrong; they exist since 2.0 just like object-add.

Struct SevGuestProperties is since 2.12, but that's also immaterial.

The members of SevGuestProperties are the variant arguments for @type
value "sev-guest".  Since they don't have their own "since" tag, they
inherit it from SevGuestProperties, i.e. since 2.12.

Your patch moves some of the members to new base type
SevCommonProperties.  As Daniel observed, you can either claim
SevCommonProperties is since 2.12 (which is a lie), or you claim 9.1 for
the type and 2.12 for all its members (which is odd).

I prefer oddities to lies.

I'm not sure we need a comment explaining the oddity.  If you think it's
useful, please make it a non-doc comment.  Reminder:

    ##
    # This is a doc comment.  It goes into generated documentation.
    ##

    # This is is not a doc comment.  It does not go into generated
    # documentation.

Comments?

[...]


  parent reply	other threads:[~2024-03-27 15:22 UTC|newest]

Thread overview: 109+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-03-20  8:38 [PATCH RFC v3 00/49] Add AMD Secure Nested Paging (SEV-SNP) support Michael Roth
2024-03-20  8:38 ` [PATCH v3 01/49] Revert "linux-headers hack" from sevinit2 base tree Michael Roth
2024-03-20  8:38 ` [PATCH v3 02/49] scripts/update-linux-headers: Add setup_data.h to import list Michael Roth
2024-03-20  9:19   ` Paolo Bonzini
2024-03-20  8:38 ` [PATCH v3 03/49] scripts/update-linux-headers: Add bits.h to file imports Michael Roth
2024-03-20  8:39 ` [PATCH v3 04/49] [HACK] linux-headers: Update headers for 6.8 + kvm-coco-queue + SNP Michael Roth
2024-03-20  8:39 ` [PATCH v3 05/49] [TEMP] hw/i386: Remove redeclaration of struct setup_data Michael Roth
2024-03-20  8:39 ` [PATCH v3 06/49] RAMBlock: Add support of KVM private guest memfd Michael Roth
2024-03-20 16:38   ` Paolo Bonzini
2024-03-20  8:39 ` [PATCH v3 07/49] HostMem: Add mechanism to opt in kvm guest memfd via MachineState Michael Roth
2025-01-21 17:39   ` Peter Xu
2025-01-21 18:24     ` David Hildenbrand
2025-01-21 20:21       ` Peter Xu
2025-01-21 20:41         ` David Hildenbrand
2025-01-21 20:59           ` Peter Xu
2025-01-21 21:00             ` David Hildenbrand
2024-03-20  8:39 ` [PATCH v3 08/49] trace/kvm: Split address space and slot id in trace_kvm_set_user_memory() Michael Roth
2024-03-20  8:39 ` [PATCH v3 09/49] kvm: Enable KVM_SET_USER_MEMORY_REGION2 for memslot Michael Roth
2024-03-20 15:56   ` Paolo Bonzini
2024-03-20  8:39 ` [PATCH v3 10/49] kvm: Introduce support for memory_attributes Michael Roth
2024-03-20 16:00   ` Paolo Bonzini
2024-03-20  8:39 ` [PATCH v3 11/49] physmem: Introduce ram_block_discard_guest_memfd_range() Michael Roth
2024-03-20  9:37   ` David Hildenbrand
2024-03-20 12:43     ` Xiaoyao Li
2024-03-20 12:58       ` David Hildenbrand
2024-03-20 17:38     ` Michael Roth
2024-03-20 20:04       ` David Hildenbrand
2024-03-21 20:24         ` Michael Roth
2024-03-20  8:39 ` [PATCH v3 12/49] kvm: handle KVM_EXIT_MEMORY_FAULT Michael Roth
2024-03-20  8:39 ` [PATCH v3 13/49] [FIXUP] "kvm: handle KVM_EXIT_MEMORY_FAULT": drop qemu_host_page_size Michael Roth
2024-03-20 12:46   ` Xiaoyao Li
2024-03-20  8:39 ` [PATCH v3 14/49] trace/kvm: Add trace for page convertion between shared and private Michael Roth
2024-03-20  8:39 ` [PATCH v3 15/49] kvm/memory: Make memory type private by default if it has guest memfd backend Michael Roth
2024-03-20  8:39 ` [PATCH v3 16/49] memory: Introduce memory_region_init_ram_guest_memfd() Michael Roth
2024-03-20  8:39 ` [PATCH v3 17/49] pci-host/q35: Move PAM initialization above SMRAM initialization Michael Roth
2024-03-20  8:39 ` [PATCH v3 18/49] q35: Introduce smm_ranges property for q35-pci-host Michael Roth
2024-03-20  8:39 ` [PATCH v3 19/49] kvm: Make kvm_convert_memory() obey ram_block_discard_is_enabled() Michael Roth
2024-03-20 16:26   ` Paolo Bonzini
2024-03-20 19:47     ` Michael Roth
2024-03-20  8:39 ` [PATCH v3 20/49] trace/kvm: Add trace for KVM_EXIT_MEMORY_FAULT Michael Roth
2024-03-20  8:39 ` [PATCH v3 21/49] i386/sev: Introduce "sev-common" type to encapsulate common SEV state Michael Roth
2024-03-20 11:44   ` Daniel P. Berrangé
2024-03-20 21:36     ` Michael Roth
2024-03-27 15:22     ` Markus Armbruster [this message]
2024-03-20 11:47   ` Daniel P. Berrangé
2024-03-20 21:45     ` Michael Roth
2024-04-22 13:06   ` Markus Armbruster
2024-03-20  8:39 ` [PATCH v3 22/49] i386/sev: Introduce 'sev-snp-guest' object Michael Roth
2024-03-20 11:58   ` Daniel P. Berrangé
2024-03-20 22:09     ` Michael Roth
2024-04-22 13:52   ` Markus Armbruster
2024-03-20  8:39 ` [PATCH v3 23/49] i386/sev: Add a sev_snp_enabled() helper Michael Roth
2024-03-20 12:35   ` Daniel P. Berrangé
2024-03-20 22:11     ` Michael Roth
2024-03-20  8:39 ` [PATCH v3 24/49] target/i386: Add handling for KVM_X86_SNP_VM VM type Michael Roth
2024-03-20  9:33   ` Paolo Bonzini
2024-03-20  8:39 ` [PATCH v3 25/49] i386/sev: Skip RAMBlock notifiers for SNP Michael Roth
2024-03-20  9:46   ` Paolo Bonzini
2024-03-20 22:14     ` Michael Roth
2024-03-20  8:39 ` [PATCH v3 26/49] i386/sev: Skip machine-init-done " Michael Roth
2024-03-20  8:39 ` [PATCH v3 27/49] i386/sev: Set ms->require_guest_memfd " Michael Roth
2024-03-20  9:48   ` Paolo Bonzini
2024-03-20  8:39 ` [PATCH v3 28/49] i386/sev: Disable SMM " Michael Roth
2024-03-20 12:32   ` Daniel P. Berrangé
2024-03-20  8:39 ` [PATCH v3 29/49] i386/sev: Don't disable block discarding " Michael Roth
2024-03-20 12:33   ` Daniel P. Berrangé
2024-03-20  8:39 ` [PATCH v3 30/49] i386/cpu: Set SEV-SNP CPUID bit when SNP enabled Michael Roth
2024-03-20  8:39 ` [PATCH v3 31/49] i386/sev: Update query-sev QAPI format to handle SEV-SNP Michael Roth
2024-03-20 12:10   ` Daniel P. Berrangé
2024-03-20 22:23     ` Michael Roth
2024-04-22 15:01   ` Markus Armbruster
2024-03-20  8:39 ` [PATCH v3 32/49] i386/sev: Don't return launch measurements for SEV-SNP guests Michael Roth
2024-03-20 12:15   ` Daniel P. Berrangé
2024-03-20 12:27     ` Daniel P. Berrangé
2024-03-20  8:39 ` [PATCH v3 33/49] kvm: Make kvm_convert_memory() non-static Michael Roth
2024-03-20  8:39 ` [PATCH v3 34/49] i386/sev: Add KVM_EXIT_VMGEXIT handling for Page State Changes Michael Roth
2024-03-20  8:39 ` [PATCH v3 35/49] i386/sev: Add KVM_EXIT_VMGEXIT handling for Page State Changes (MSR-based) Michael Roth
2024-03-20  8:39 ` [PATCH v3 36/49] i386/sev: Add KVM_EXIT_VMGEXIT handling for Extended Guest Requests Michael Roth
2024-04-22 15:02   ` Markus Armbruster
2024-03-20  8:39 ` [PATCH v3 37/49] i386/sev: Add the SNP launch start context Michael Roth
2024-03-20  9:58   ` Paolo Bonzini
2024-03-20 22:32     ` Michael Roth
2024-03-20  8:39 ` [PATCH v3 38/49] i386/sev: Add handling to encrypt/finalize guest launch data Michael Roth
2024-03-20  8:39 ` [PATCH v3 39/49] i386/sev: Set CPU state to protected once SNP guest payload is finalized Michael Roth
2024-03-20  8:39 ` [PATCH v3 40/49] hw/i386/sev: Add function to get SEV metadata from OVMF header Michael Roth
2024-03-20 17:55   ` Isaku Yamahata
2024-03-20 22:35     ` Michael Roth
2024-03-20  8:39 ` [PATCH v3 41/49] i386/sev: Add support for populating OVMF metadata pages Michael Roth
2024-03-20  8:39 ` [PATCH v3 42/49] i386/sev: Add support for SNP CPUID validation Michael Roth
2024-03-20 12:18   ` Daniel P. Berrangé
2024-03-20  8:39 ` [PATCH v3 43/49] qapi, i386: Move kernel-hashes to SevCommonProperties Michael Roth
2024-03-20 12:20   ` Daniel P. Berrangé
2024-04-22 15:03     ` Markus Armbruster
2024-03-20  8:39 ` [PATCH v3 44/49] i386/sev: Extract build_kernel_loader_hashes Michael Roth
2024-03-20  8:39 ` [PATCH v3 45/49] i386/sev: Reorder struct declarations Michael Roth
2024-03-20  8:39 ` [PATCH v3 46/49] i386/sev: Allow measured direct kernel boot on SNP Michael Roth
2024-03-20  8:39 ` [PATCH v3 47/49] hw/i386/sev: Add support to encrypt BIOS when SEV-SNP is enabled Michael Roth
2024-03-20 12:22   ` Daniel P. Berrangé
2024-03-21 13:42     ` Michael Roth
2024-03-20  8:39 ` [PATCH v3 48/49] hw/i386/sev: Use guest_memfd for legacy ROMs Michael Roth
2024-03-20 18:12   ` Isaku Yamahata
2024-03-28  0:45     ` Xiaoyao Li
2024-04-24  0:08       ` Michael Roth
2024-03-20  8:39 ` [PATCH v3 49/49] hw/i386: Add support for loading BIOS using guest_memfd Michael Roth
2024-03-20  9:59 ` [PATCH RFC v3 00/49] Add AMD Secure Nested Paging (SEV-SNP) support Paolo Bonzini
2024-03-20 17:08   ` Paolo Bonzini
2024-03-20 20:54     ` Xiaoyao Li
2024-03-21 20:26 ` Michael Roth
2024-04-18 11:37 ` Ani Sinha

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87h6gritsx.fsf@pond.sub.org \
    --to=armbru@redhat.com \
    --cc=berrange@redhat.com \
    --cc=isaku.yamahata@linux.intel.com \
    --cc=kvm@vger.kernel.org \
    --cc=michael.roth@amd.com \
    --cc=pankaj.gupta@amd.com \
    --cc=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=thomas.lendacky@amd.com \
    --cc=xiaoyao.li@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox