linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Maxim Levitsky <mlevitsk@redhat.com>
To: Nicolas Saenz Julienne <nsaenz@amazon.com>, kvm@vger.kernel.org
Cc: linux-kernel@vger.kernel.org, linux-hyperv@vger.kernel.org,
	pbonzini@redhat.com, seanjc@google.com, vkuznets@redhat.com,
	anelkz@amazon.com, graf@amazon.com, dwmw@amazon.co.uk,
	jgowans@amazon.com, corbert@lwn.net, kys@microsoft.com,
	haiyangz@microsoft.com, decui@microsoft.com, x86@kernel.org,
	linux-doc@vger.kernel.org
Subject: Re: [RFC 33/33] Documentation: KVM: Introduce "Emulating Hyper-V VSM with KVM"
Date: Tue, 28 Nov 2023 10:19:59 +0200	[thread overview]
Message-ID: <b5dcd218828f056d68ac8510c768f7792467ef6f.camel@redhat.com> (raw)
In-Reply-To: <20231108111806.92604-34-nsaenz@amazon.com>

On Wed, 2023-11-08 at 11:18 +0000, Nicolas Saenz Julienne wrote:
> Introduce "Emulating Hyper-V VSM with KVM", which describes the KVM APIs
> made available to a VMM that wants to emulate Hyper-V's VSM.
> 
> Signed-off-by: Nicolas Saenz Julienne <nsaenz@amazon.com>
> ---
>  .../virt/kvm/x86/emulating-hyperv-vsm.rst     | 136 ++++++++++++++++++
>  1 file changed, 136 insertions(+)
>  create mode 100644 Documentation/virt/kvm/x86/emulating-hyperv-vsm.rst
> 
> diff --git a/Documentation/virt/kvm/x86/emulating-hyperv-vsm.rst b/Documentation/virt/kvm/x86/emulating-hyperv-vsm.rst
> new file mode 100644
> index 000000000000..8f76bf09c530
> --- /dev/null
> +++ b/Documentation/virt/kvm/x86/emulating-hyperv-vsm.rst
> @@ -0,0 +1,136 @@
> +.. SPDX-License-Identifier: GPL-2.0
> +
> +==============================
> +Emulating Hyper-V VSM with KVM
> +==============================
> +
> +Hyper-V's Virtual Secure Mode (VSM) is a virtualisation security feature
> +that leverages the hypervisor to create secure execution environments
> +within a guest. VSM is documented as part of Microsoft's Hypervisor Top
> +Level Functional Specification[1].
> +
> +Emulating Hyper-V's Virtual Secure Mode with KVM requires coordination
> +between KVM and the VMM. Most of the VSM state and configuration is left
> +to be handled by user-space, but some has made its way into KVM. This
> +document describes the mechanisms through which a VMM can implement VSM
> +support.
> +
> +Virtual Trust Levels
> +--------------------
> +
> +The main concept VSM introduces are Virtual Trust Levels or VTLs. Each
> +VTL is a CPU mode, with its own private CPU architectural state,
> +interrupt subsystem (limited to a local APIC), and memory access
> +permissions. VTLs are hierarchical, where VTL0 corresponds to normal
> +guest execution and VTL > 0 to privileged execution contexts. In
> +practice, when virtualising Windows on top of KVM, we only see VTL0 and
> +VTL1. Although the spec allows going all the way to VTL15. VTLs are
> +orthogonal to ring levels, so each VTL is capable of runnig its own
> +operating system and user-space[2].
> +
> +  ┌──────────────────────────────��? ┌──────────────────────────────��?
> +  │ Normal Mode (VTL0)           │ │ Secure Mode (VTL1)           │
> +  │ ┌──────────────────────────��? │ │ ┌──────────────────────────��? │
> +  │ │   User-mode Processes    │ │ │ │Secure User-mode Processes│ │
> +  │ └──────────────────────────┘ │ │ └──────────────────────────┘ │
> +  │ ┌──────────────────────────��? │ │ ┌──────────────────────────��? │
> +  │ │         Kernel           │ │ │ │      Secure Kernel       │ │
> +  │ └──────────────────────────┘ │ │ └──────────────────────────┘ │
> +  └──────────────────────────────┘ └──────────────────────────────┘
> +  ┌───────────────────────────────────────────────────────────────��?
> +  │                         Hypervisor/KVM                        │
> +  └───────────────────────────────────────────────────────────────┘
> +  ┌───────────────────────────────────────────────────────────────��?
> +  │                           Hardware                            │
> +  └───────────────────────────────────────────────────────────────┘
> +
> +VTLs break the core assumption that a vCPU has a single architectural
> +state, lAPIC state, SynIC state, etc. As such, each VTL is modeled as a
> +distinct KVM vCPU, with the restriction that only one is allowed to run
> +at any moment in time. Having multiple KVM vCPUs tracking a single guest
> +CPU complicates vCPU numbering. VMs that enable VSM are expected to use
> +CAP_APIC_ID_GROUPS to segregate vCPUs (and their lAPICs) into different
> +groups. For example, a 4 CPU VSM VM will setup the APIC ID groups feature
> +so only the first two bits of the APIC ID are exposed to the guest. The
> +remaining bits represent the vCPU's VTL. The 'sibling' vCPU to VTL0's
> +vCPU2 at VTL3 will have an APIC ID of 0xE. Using this approach a VMM and
> +KVM are capable of querying a vCPU's VTL, or finding the vCPU associated
> +to a specific VTL.
> +
> +KVM's lAPIC implementation is aware of groups, and takes note of the
> +source vCPU's group when delivering IPIs. As such, it shouldn't be
> +possible to target a different VTL through the APIC. Interrupts are
> +delivered to the vCPU's lAPIC subsystem regardless of the VTL's runstate,
> +this also includes timers. Ultimately, any interrupt incoming from an
> +outside source (IOAPIC/MSIs) is routed to VTL0.
> +
> +Moving Between VTLs
> +-------------------
> +
> +All VSM configuration and VTL handling hypercalls are passed through to
> +user-space. Notably the two primitives that allow switching between VTLs.
> +All shared state synchronization and KVM vCPU scheduling is left to the
> +VMM to manage. For example, upon receiving a VTL call, the VMM stops the
> +vCPU that issued the hypercall, and schedules the vCPU corresponding to
> +the next privileged VTL. When that privileged vCPU is done executing, it
> +issues a VTL return hypercall, so the opposite operation happens. All
> +this is transparent to KVM, which limits itself to running vCPUs.
> +
> +An interrupt directed at a privileged VTL always has precedence over the
> +execution of lower VTLs. To honor this, the VMM can monitor events
> +targeted at privileged vCPUs with poll(), and should trigger an
> +asynchronous VTL switch whenever events become available. Additionally,
> +the target VTL's vCPU VP assist overlay page is used to notify the target
> +VTL with the reason for the switch. The VMM can keep track of the VP
> +assist page by installing an MSR filter for HV_X64_MSR_VP_ASSIST_PAGE.
> +
> +Hyper-V VP registers
> +--------------------
> +
> +VP register hypercalls are passed through to user-space. All requests can
> +be fulfilled either by using already existing KVM state ioctls, or are
> +related to VSM's configuration, which is already handled by the VMM. Note
> +that HV_REGISTER_VSM_CODE_PAGE_OFFSETS is the only VSM specific VP
> +register the kernel controls, as such it is made available through the
> +KVM_HV_GET_VSM_STATE ioctl.
> +
> +Per-VTL Memory Protections
> +--------------------------
> +
> +A privileged VTL can change the memory access restrictions of lower VTLs.
> +It does so to hide secrets from them, or to control what they are allowed
> +to execute. The list of memory protections allowed is[3]:
> + - No access
> + - Read-only, no execute
> + - Read-only, execute
> + - Read/write, no execute
> + - Read/write, execute
> +
> +VTL memory protection hypercalls are passed through to user-space, but
> +KVM provides an interface that allows changing memory protections on a
> +per-VTL basis. This is made possible by the KVM VTL device. VMMs can
> +create one per VTL and it exposes a ioctl, KVM_SET_MEMORY_ATTRIBUTES,
> +that controls the memory protections applied to that VTL. The KVM TDP MMU
> +is VTL aware and page faults are resolved taking into account the
> +corresponding VTL device's memory attributes.
> +
> +When a memory access violates VTL memory protections, KVM issues a secure
> +memory intercept, which is passed as a SynIC message into the next
> +privileged VTL. This happens transparently for the VMM. Additionally, KVM
> +exits with a user-space memory fault. This allows the VMM to stop the
> +vCPU while the secure intercept is handled by the privileged VTL. In the
> +good case, the instruction that triggered the fault is emulated and
> +control is returned to the lower VTL, in the bad case, Windows crashes
> +gracefully.
> +
> +Hyper-V's TLFS also states that DMA should follow VTL0's memory access
> +restrictions. This is out of scope for this document, as IOMMU mappings
> +are not handled by KVM.
> +
> +[1] https://raw.githubusercontent.com/Microsoft/Virtualization-Documentation/master/tlfs/Hypervisor%20Top%20Level%20Functional%20Specification%20v6.0b.pdf
> +
> +[2] Conceptually this design is similar to arm's TrustZone: The
> +hypervisor plays the role of EL3. Windows (VTL0) runs in Non-Secure
> +(EL0/EL1) and the secure kernel (VTL1) in Secure World (EL1s/EL0s).
> +
> +[3] TLFS 15.9.3

As Sean said, we should also document on how VTL support is implemented in the KVM (e.g things that matter to KVM developers),
but the above information is also very useful and should be kept.


Best regards,
	Maxim Levitsky



  reply	other threads:[~2023-11-28  8:20 UTC|newest]

Thread overview: 108+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-11-08 11:17 [RFC 0/33] KVM: x86: hyperv: Introduce VSM support Nicolas Saenz Julienne
2023-11-08 11:17 ` [RFC 01/33] KVM: x86: Decouple lapic.h from hyperv.h Nicolas Saenz Julienne
2023-11-08 16:11   ` Sean Christopherson
2023-11-08 11:17 ` [RFC 02/33] KVM: x86: Introduce KVM_CAP_APIC_ID_GROUPS Nicolas Saenz Julienne
2023-11-08 12:11   ` Alexander Graf
2023-11-08 17:47   ` Sean Christopherson
2023-11-10 18:46     ` Nicolas Saenz Julienne
2023-11-28  6:56   ` Maxim Levitsky
2023-12-01 15:25     ` Nicolas Saenz Julienne
2023-11-08 11:17 ` [RFC 03/33] KVM: x86: hyper-v: Introduce XMM output support Nicolas Saenz Julienne
2023-11-08 11:44   ` Alexander Graf
2023-11-08 12:11     ` Vitaly Kuznetsov
2023-11-08 12:16       ` Alexander Graf
2023-11-28  6:57         ` Maxim Levitsky
2023-11-08 11:17 ` [RFC 04/33] KVM: x86: hyper-v: Move hypercall page handling into separate function Nicolas Saenz Julienne
2023-11-28  7:01   ` Maxim Levitsky
2023-11-08 11:17 ` [RFC 05/33] KVM: x86: hyper-v: Introduce VTL call/return prologues in hypercall page Nicolas Saenz Julienne
2023-11-08 11:53   ` Alexander Graf
2023-11-08 14:10     ` Nicolas Saenz Julienne
2023-11-28  7:08   ` Maxim Levitsky
2023-11-28 16:33     ` Sean Christopherson
2023-12-01 16:19     ` Nicolas Saenz Julienne
2023-12-01 16:32       ` Sean Christopherson
2023-12-01 16:50         ` Nicolas Saenz Julienne
2023-12-01 17:47           ` Sean Christopherson
2023-12-01 18:15             ` Nicolas Saenz Julienne
2023-12-05 19:21               ` Sean Christopherson
2023-12-05 20:04                 ` Maxim Levitsky
2023-12-06  0:07                   ` Sean Christopherson
2023-12-06 16:19                     ` Maxim Levitsky
2023-11-08 11:17 ` [RFC 06/33] KVM: x86: hyper-v: Introduce VTL awareness to Hyper-V's PV-IPIs Nicolas Saenz Julienne
2023-11-28  7:14   ` Maxim Levitsky
2023-12-01 16:31     ` Nicolas Saenz Julienne
2023-12-05 15:02       ` Maxim Levitsky
2023-11-08 11:17 ` [RFC 07/33] KVM: x86: hyper-v: Introduce KVM_CAP_HYPERV_VSM Nicolas Saenz Julienne
2023-11-28  7:16   ` Maxim Levitsky
2023-11-08 11:17 ` [RFC 08/33] KVM: x86: Don't use hv_timer if CAP_HYPERV_VSM enabled Nicolas Saenz Julienne
2023-11-28  7:21   ` Maxim Levitsky
2023-11-08 11:17 ` [RFC 09/33] KVM: x86: hyper-v: Introduce per-VTL vcpu helpers Nicolas Saenz Julienne
2023-11-08 12:21   ` Alexander Graf
2023-11-08 14:04     ` Nicolas Saenz Julienne
2023-11-28  7:25   ` Maxim Levitsky
2023-11-08 11:17 ` [RFC 10/33] KVM: x86: hyper-v: Introduce KVM_HV_GET_VSM_STATE Nicolas Saenz Julienne
2023-11-28  7:26   ` Maxim Levitsky
2023-11-08 11:17 ` [RFC 11/33] KVM: x86: hyper-v: Handle GET/SET_VP_REGISTER hcall in user-space Nicolas Saenz Julienne
2023-11-08 12:14   ` Alexander Graf
2023-11-28  7:26     ` Maxim Levitsky
2023-11-08 11:17 ` [RFC 12/33] KVM: x86: hyper-v: Handle VSM hcalls " Nicolas Saenz Julienne
2023-11-28  7:28   ` Maxim Levitsky
2023-11-08 11:17 ` [RFC 13/33] KVM: Allow polling vCPUs for events Nicolas Saenz Julienne
2023-11-28  7:30   ` Maxim Levitsky
2023-11-08 11:17 ` [RFC 14/33] KVM: x86: Add VTL to the MMU role Nicolas Saenz Julienne
2023-11-08 17:26   ` Sean Christopherson
2023-11-10 18:52     ` Nicolas Saenz Julienne
2023-11-28  7:34       ` Maxim Levitsky
2023-11-08 11:17 ` [RFC 15/33] KVM: x86/mmu: Introduce infrastructure to handle non-executable faults Nicolas Saenz Julienne
2023-11-28  7:34   ` Maxim Levitsky
2023-11-08 11:17 ` [RFC 16/33] KVM: x86/mmu: Expose R/W/X flags during memory fault exits Nicolas Saenz Julienne
2023-11-28  7:36   ` Maxim Levitsky
2023-11-28 16:31     ` Sean Christopherson
2023-11-08 11:17 ` [RFC 17/33] KVM: x86/mmu: Allow setting memory attributes if VSM enabled Nicolas Saenz Julienne
2023-11-28  7:39   ` Maxim Levitsky
2023-11-08 11:17 ` [RFC 18/33] KVM: x86: Decouple kvm_get_memory_attributes() from struct kvm's mem_attr_array Nicolas Saenz Julienne
2023-11-08 16:59   ` Sean Christopherson
2023-11-28  7:41   ` Maxim Levitsky
2023-11-08 11:17 ` [RFC 19/33] KVM: x86: Decouple kvm_range_has_memory_attributes() " Nicolas Saenz Julienne
2023-11-28  7:42   ` Maxim Levitsky
2023-11-08 11:17 ` [RFC 20/33] KVM: x86/mmu: Decouple hugepage_has_attrs() " Nicolas Saenz Julienne
2023-11-28  7:43   ` Maxim Levitsky
2023-11-08 11:17 ` [RFC 21/33] KVM: Pass memory attribute array as a MMU notifier argument Nicolas Saenz Julienne
2023-11-08 17:08   ` Sean Christopherson
2023-11-08 11:17 ` [RFC 22/33] KVM: Decouple kvm_ioctl_set_mem_attributes() from kvm's mem_attr_array Nicolas Saenz Julienne
2023-11-08 11:17 ` [RFC 23/33] KVM: Expose memory attribute helper functions unanimously Nicolas Saenz Julienne
2023-11-08 11:17 ` [RFC 24/33] KVM: x86: hyper-v: Introduce KVM VTL device Nicolas Saenz Julienne
2023-11-08 11:17 ` [RFC 25/33] KVM: Introduce a set of new memory attributes Nicolas Saenz Julienne
2023-11-08 12:30   ` Alexander Graf
2023-11-08 16:43     ` Sean Christopherson
2023-11-08 11:17 ` [RFC 26/33] KVM: x86: hyper-vsm: Allow setting per-VTL " Nicolas Saenz Julienne
2023-11-28  7:44   ` Maxim Levitsky
2023-11-08 11:18 ` [RFC 27/33] KVM: x86/mmu/hyper-v: Validate memory faults against per-VTL memprots Nicolas Saenz Julienne
2023-11-28  7:46   ` Maxim Levitsky
2023-11-08 11:18 ` [RFC 28/33] x86/hyper-v: Introduce memory intercept message structure Nicolas Saenz Julienne
2023-11-28  7:53   ` Maxim Levitsky
2023-11-08 11:18 ` [RFC 29/33] KVM: VMX: Save instruction length on EPT violation Nicolas Saenz Julienne
2023-11-08 12:40   ` Alexander Graf
2023-11-08 16:15     ` Sean Christopherson
2023-11-08 17:11       ` Alexander Graf
2023-11-08 17:20   ` Sean Christopherson
2023-11-08 17:27     ` Alexander Graf
2023-11-08 18:19       ` Jim Mattson
2023-11-08 11:18 ` [RFC 30/33] KVM: x86: hyper-v: Introduce KVM_REQ_HV_INJECT_INTERCEPT request Nicolas Saenz Julienne
2023-11-08 12:45   ` Alexander Graf
2023-11-08 13:38     ` Nicolas Saenz Julienne
2023-11-28  8:19       ` Maxim Levitsky
2023-11-08 11:18 ` [RFC 31/33] KVM: x86: hyper-v: Inject intercept on VTL memory protection fault Nicolas Saenz Julienne
2023-11-08 11:18 ` [RFC 32/33] KVM: x86: hyper-v: Implement HVCALL_TRANSLATE_VIRTUAL_ADDRESS Nicolas Saenz Julienne
2023-11-08 12:49   ` Alexander Graf
2023-11-08 13:44     ` Nicolas Saenz Julienne
2023-11-08 11:18 ` [RFC 33/33] Documentation: KVM: Introduce "Emulating Hyper-V VSM with KVM" Nicolas Saenz Julienne
2023-11-28  8:19   ` Maxim Levitsky [this message]
2023-11-08 11:40 ` [RFC 0/33] KVM: x86: hyperv: Introduce VSM support Alexander Graf
2023-11-08 14:41   ` Nicolas Saenz Julienne
2023-11-08 16:55 ` Sean Christopherson
2023-11-08 18:33   ` Sean Christopherson
2023-11-10 17:56     ` Nicolas Saenz Julienne
2023-11-10 19:32       ` Sean Christopherson
2023-11-11 11:55         ` Nicolas Saenz Julienne
2023-11-10 19:04   ` Nicolas Saenz Julienne

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=b5dcd218828f056d68ac8510c768f7792467ef6f.camel@redhat.com \
    --to=mlevitsk@redhat.com \
    --cc=anelkz@amazon.com \
    --cc=corbert@lwn.net \
    --cc=decui@microsoft.com \
    --cc=dwmw@amazon.co.uk \
    --cc=graf@amazon.com \
    --cc=haiyangz@microsoft.com \
    --cc=jgowans@amazon.com \
    --cc=kvm@vger.kernel.org \
    --cc=kys@microsoft.com \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-hyperv@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=nsaenz@amazon.com \
    --cc=pbonzini@redhat.com \
    --cc=seanjc@google.com \
    --cc=vkuznets@redhat.com \
    --cc=x86@kernel.org \
    /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;
as well as URLs for NNTP newsgroup(s).