From: "Daniel P. Berrangé" <berrange@redhat.com>
To: Srivatsa Vaddagiri <quic_svaddagi@quicinc.com>
Cc: peter.maydell@linaro.org, philmd@linaro.org,
alex.bennee@linaro.org, qemu-devel@nongnu.org,
qemu-arm@nongnu.org, quic_tsoni@quicinc.com,
quic_pheragu@quicinc.com, quic_eberman@quicinc.com,
quic_yvasi@quicinc.com, quic_cvanscha@quicinc.com,
quic_mnalajal@quicinc.com
Subject: Re: [RFC/PATCH v2 03/12] hw/arm/virt: confidential guest support
Date: Thu, 16 May 2024 16:04:24 +0100 [thread overview]
Message-ID: <ZkYgeGSPxD_yt5oa@redhat.com> (raw)
In-Reply-To: <20240516143356.1739402-4-quic_svaddagi@quicinc.com>
On Thu, May 16, 2024 at 02:33:47PM +0000, Srivatsa Vaddagiri wrote:
> This adds support to launch hypervisor-assisted confidential guests,
> where guest's memory is protected from a potentially untrusted host.
> Hypervisor can setup host's page-tables so that it loses access to guest
> memory.
>
> Since some guest drivers may need to communicate data with their host
> counterparts via shared memory, optionally allow setting aside some part
> of the confidential guest's memory as "shared". The size of this shared
> memory is specified via the optional "swiotlb-size" parameter.
>
> -machine virt,confidential-guest-support=prot0 \
> -object arm-confidential-guest,id=prot0,swiotlb-size=16777216
>
> The size of this shared memory is indicated to the guest in size/reg
> property of device-tree node "/reserved-memory/restricted_dma_reserved".
> A memory-region property is added to device-tree node representing
> virtio-pcie hub, so that all DMA allocations requested by guest's virtio-pcie
> device drivers are satisfied from the shared swiotlb region.
For reference, there is another series proposing confidential guest
support for the 'virt' machine on AArch64 with KVM
https://lists.nongnu.org/archive/html/qemu-devel/2024-04/msg02742.html
I've no idea how closely your impl matches the KVM proposed impl. ie
whether we need 2 distinct "ConfidentialGuest" subclasses for KVM vs
Gunyah, or whether 1 can cope with both. If we do need 2 distinct
subclasses for each hypervisor, then calling this Gunyah targetted
object 'arm-confidential-guest' is too broad of an name.
>
> Signed-off-by: Srivatsa Vaddagiri <quic_svaddagi@quicinc.com>
> ---
> qapi/qom.json | 14 +++++
> include/hw/arm/virt.h | 1 +
> hw/arm/virt.c | 141 +++++++++++++++++++++++++++++++++++++++++-
> 3 files changed, 155 insertions(+), 1 deletion(-)
>
> diff --git a/qapi/qom.json b/qapi/qom.json
> index 38dde6d785..9b3cd7ce22 100644
> --- a/qapi/qom.json
> +++ b/qapi/qom.json
> @@ -874,6 +874,18 @@
> 'base': 'RngProperties',
> 'data': { '*filename': 'str' } }
>
> +##
> +# @ArmConfidentialGuestProperties:
> +#
> +# Properties for arm-confidential-guest objects.
> +#
> +# @swiotlb-size: swiotlb size
> +#
> +# Since: 2.12
> +##
> +{ 'struct': 'ArmConfidentialGuestProperties',
> + 'data': { 'swiotlb-size' : 'uint64' } }
> +
> ##
> # @SevGuestProperties:
> #
> @@ -997,6 +1009,7 @@
> { 'name': 'secret_keyring',
> 'if': 'CONFIG_SECRET_KEYRING' },
> 'sev-guest',
> + 'arm-confidential-guest',
> 'thread-context',
> 's390-pv-guest',
> 'throttle-group',
> @@ -1067,6 +1080,7 @@
> 'secret_keyring': { 'type': 'SecretKeyringProperties',
> 'if': 'CONFIG_SECRET_KEYRING' },
> 'sev-guest': 'SevGuestProperties',
> + 'arm-confidential-guest': 'ArmConfidentialGuestProperties',
> 'thread-context': 'ThreadContextProperties',
> 'throttle-group': 'ThrottleGroupProperties',
> 'tls-creds-anon': 'TlsCredsAnonProperties',
> diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
> index bb486d36b1..1e23f20972 100644
> --- a/include/hw/arm/virt.h
> +++ b/include/hw/arm/virt.h
> @@ -165,6 +165,7 @@ struct VirtMachineState {
> uint32_t clock_phandle;
> uint32_t gic_phandle;
> uint32_t msi_phandle;
> + uint32_t restricted_dma_phandle;
> uint32_t iommu_phandle;
> int psci_conduit;
> hwaddr highest_gpa;
> diff --git a/hw/arm/virt.c b/hw/arm/virt.c
> index 3c93c0c0a6..2a3eb4075d 100644
> --- a/hw/arm/virt.c
> +++ b/hw/arm/virt.c
> @@ -84,6 +84,9 @@
> #include "hw/virtio/virtio-iommu.h"
> #include "hw/char/pl011.h"
> #include "qemu/guest-random.h"
> +#include "sysemu/cpus.h"
> +#include "exec/confidential-guest-support.h"
> +#include "qom/object_interfaces.h"
>
> static GlobalProperty arm_virt_compat[] = {
> { TYPE_VIRTIO_IOMMU_PCI, "aw-bits", "48" },
> @@ -1545,6 +1548,11 @@ static void create_pcie(VirtMachineState *vms)
> nr_pcie_buses - 1);
> qemu_fdt_setprop(ms->fdt, nodename, "dma-coherent", NULL, 0);
>
> + if (vms->restricted_dma_phandle) {
> + qemu_fdt_setprop_cell(ms->fdt, nodename, "memory-region",
> + vms->restricted_dma_phandle);
> + }
> +
> if (vms->msi_phandle) {
> qemu_fdt_setprop_cells(ms->fdt, nodename, "msi-map",
> 0, vms->msi_phandle, 0, 0x10000);
> @@ -2065,6 +2073,129 @@ static void virt_cpu_post_init(VirtMachineState *vms, MemoryRegion *sysmem)
> }
> }
>
> +#define TYPE_ARM_CONFIDENTIAL_GUEST "arm-confidential-guest"
> +OBJECT_DECLARE_SIMPLE_TYPE(ArmConfidentialGuestState, ARM_CONFIDENTIAL_GUEST)
> +
> +struct ArmConfidentialGuestState {
> + ConfidentialGuestSupport parent_obj;
> +
> + hwaddr swiotlb_size;
> +};
> +
> +static ArmConfidentialGuestState *acg;
> +
> +static void
> +arm_confidential_guest_instance_init(Object *obj)
> +{
> + ArmConfidentialGuestState *acg = ARM_CONFIDENTIAL_GUEST(obj);
> +
> + object_property_add_uint64_ptr(obj, "swiotlb-size", &acg->swiotlb_size,
> + OBJ_PROP_FLAG_READWRITE);
> +}
> +
> +static const TypeInfo confidential_guest_info = {
> + .parent = TYPE_CONFIDENTIAL_GUEST_SUPPORT,
> + .name = TYPE_ARM_CONFIDENTIAL_GUEST,
> + .instance_size = sizeof(ArmConfidentialGuestState),
> + .instance_init = arm_confidential_guest_instance_init,
> + .interfaces = (InterfaceInfo[]) {
> + { TYPE_USER_CREATABLE },
> + { }
> + }
> +};
> +
> +static void
> +confidential_guest_register_types(void)
> +{
> + type_register_static(&confidential_guest_info);
> +}
> +type_init(confidential_guest_register_types);
> +
> +static int confidential_guest_init(MachineState *ms)
> +{
> + ConfidentialGuestSupport *cgs = ms->cgs;
> + ArmConfidentialGuestState *obj = (ArmConfidentialGuestState *)
> + object_dynamic_cast(OBJECT(cgs), TYPE_ARM_CONFIDENTIAL_GUEST);
> + const AccelOpsClass *ops = cpus_get_accel();
> +
> + if (!obj) {
> + return 0;
> + }
> +
> + if (!ops->check_capability ||
> + !ops->check_capability(CONFIDENTIAL_GUEST_SUPPORTED)) {
> + error_report("confidential guests are not supported");
> + return -1;
> + }
> +
> + if (obj->swiotlb_size > ms->ram_size) {
> + error_report("swiotlb_size exceeds RAM size");
> + return -1;
> + }
> +
> + acg = obj;
> + cgs->ready = true;
> +
> + return 0;
> +}
> +
> +static void fdt_add_reserved_memory(VirtMachineState *vms)
> +{
> + MachineState *ms = MACHINE(vms);
> + hwaddr membase = vms->memmap[VIRT_MEM].base;
> + hwaddr memsize = ms->ram_size;
> + hwaddr resv_start;
> + const char compat[] = "restricted-dma-pool";
> + const AccelOpsClass *ops = cpus_get_accel();
> + char *nodename;
> +
> + if (!acg || !acg->swiotlb_size) {
> + return;
> + }
> +
> + nodename = g_strdup_printf("/reserved-memory");
> +
> + qemu_fdt_add_subnode(ms->fdt, nodename);
> + qemu_fdt_setprop_cell(ms->fdt, nodename, "#address-cells", 2);
> + qemu_fdt_setprop_cell(ms->fdt, nodename, "#size-cells", 2);
> + qemu_fdt_setprop(ms->fdt, nodename, "ranges", NULL, 0);
> + g_free(nodename);
> +
> + resv_start = membase + memsize - acg->swiotlb_size;
> + if (ops->check_capability &&
> + ops->check_capability(CONFIDENTIAL_GUEST_CAN_SHARE_MEM_WITH_HOST)) {
> + /*
> + * Indicate only the size of swiotlb buffer needed. Guest will
> + * determine where in its private memory the buffer will be placed and
> + * will use appropriate (hypervisor) APIs to share that with host.
> + */
> + nodename = g_strdup_printf("/reserved-memory/restricted_dma_reserved");
> + qemu_fdt_add_subnode(ms->fdt, nodename);
> + qemu_fdt_setprop_cell(ms->fdt, nodename, "size", acg->swiotlb_size);
> + qemu_fdt_setprop_cell(ms->fdt, nodename, "alignment", 4096);
> + } else {
> + /*
> + * On hypervisors that don't support APIs for guest to share
> + * its (private) memory with host, indicate to the guest where in its
> + * address space shared memory can be found. Host should make arrangents
> + * with hypervisor to assign some memory to guest at the indicated range
> + * and mark it as shared.
> + */
> + nodename = g_strdup_printf("/reserved-memory/restricted_dma_reserved@%"
> + PRIx64, resv_start);
> + qemu_fdt_add_subnode(ms->fdt, nodename);
> + qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "reg",
> + 2, resv_start,
> + 2, acg->swiotlb_size);
> + }
> +
> + vms->restricted_dma_phandle = qemu_fdt_alloc_phandle(ms->fdt);
> + qemu_fdt_setprop_cell(ms->fdt, nodename, "phandle",
> + vms->restricted_dma_phandle);
> + qemu_fdt_setprop(ms->fdt, nodename, "compatible", compat, sizeof(compat));
> + g_free(nodename);
> +}
> +
> static void machvirt_init(MachineState *machine)
> {
> VirtMachineState *vms = VIRT_MACHINE(machine);
> @@ -2075,7 +2206,7 @@ static void machvirt_init(MachineState *machine)
> MemoryRegion *secure_sysmem = NULL;
> MemoryRegion *tag_sysmem = NULL;
> MemoryRegion *secure_tag_sysmem = NULL;
> - int n, virt_max_cpus;
> + int n, virt_max_cpus, ret;
> bool firmware_loaded;
> bool aarch64 = true;
> bool has_ged = !vmc->no_ged;
> @@ -2084,6 +2215,12 @@ static void machvirt_init(MachineState *machine)
>
> possible_cpus = mc->possible_cpu_arch_ids(machine);
>
> + ret = confidential_guest_init(machine);
> + if (ret != 0) {
> + error_report("Failed to initialize confidential guest");
> + exit(1);
> + }
> +
> /*
> * In accelerated mode, the memory map is computed earlier in kvm_type()
> * to create a VM with the right number of IPA bits.
> @@ -2195,6 +2332,8 @@ static void machvirt_init(MachineState *machine)
>
> create_fdt(vms);
>
> + fdt_add_reserved_memory(vms);
> +
> assert(possible_cpus->len == max_cpus);
> for (n = 0; n < possible_cpus->len; n++) {
> Object *cpuobj;
> --
> 2.25.1
>
>
With regards,
Daniel
--
|: https://berrange.com -o- https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o- https://fstop138.berrange.com :|
|: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|
next prev parent reply other threads:[~2024-05-16 15:05 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-05-16 14:33 [RFC/PATCH v2 00/12] Gunyah hypervisor support Srivatsa Vaddagiri
2024-05-16 14:33 ` [RFC/PATCH v2 01/12] gunyah: UAPI header (NOT FOR MERGE) Srivatsa Vaddagiri
2024-05-16 14:33 ` [RFC/PATCH v2 02/12] accel: Introduce check_capability() callback Srivatsa Vaddagiri
2024-05-16 14:33 ` [RFC/PATCH v2 03/12] hw/arm/virt: confidential guest support Srivatsa Vaddagiri
2024-05-16 15:04 ` Daniel P. Berrangé [this message]
2024-05-16 19:41 ` Srivatsa Vaddagiri
2024-05-16 14:33 ` [RFC/PATCH v2 04/12] gunyah: Basic support Srivatsa Vaddagiri
2024-05-16 14:33 ` [RFC/PATCH v2 05/12] gunyah: Support memory assignment Srivatsa Vaddagiri
2024-05-16 14:33 ` [RFC/PATCH v2 06/12] gunyah: Add IRQFD and IOEVENTFD functions Srivatsa Vaddagiri
2024-05-16 14:33 ` [RFC/PATCH v2 07/12] gunyah: Add gicv3 interrupt controller Srivatsa Vaddagiri
2024-05-16 14:33 ` [RFC/PATCH v2 08/12] gunyah: Specific device-tree location Srivatsa Vaddagiri
2024-05-16 14:33 ` [RFC/PATCH v2 09/12] gunyah: Customize device-tree Srivatsa Vaddagiri
2024-05-16 14:33 ` [RFC/PATCH v2 10/12] gunyah: CPU execution loop Srivatsa Vaddagiri
2024-05-16 14:33 ` [RFC/PATCH v2 11/12] gunyah: Workarounds (NOT FOR MERGE) Srivatsa Vaddagiri
2024-05-16 14:33 ` [RFC/PATCH v2 12/12] gunyah: Documentation Srivatsa Vaddagiri
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=ZkYgeGSPxD_yt5oa@redhat.com \
--to=berrange@redhat.com \
--cc=alex.bennee@linaro.org \
--cc=peter.maydell@linaro.org \
--cc=philmd@linaro.org \
--cc=qemu-arm@nongnu.org \
--cc=qemu-devel@nongnu.org \
--cc=quic_cvanscha@quicinc.com \
--cc=quic_eberman@quicinc.com \
--cc=quic_mnalajal@quicinc.com \
--cc=quic_pheragu@quicinc.com \
--cc=quic_svaddagi@quicinc.com \
--cc=quic_tsoni@quicinc.com \
--cc=quic_yvasi@quicinc.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;
as well as URLs for NNTP newsgroup(s).