qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Gavin Shan <gshan@redhat.com>
To: Jean-Philippe Brucker <jean-philippe@linaro.org>,
	peter.maydell@linaro.org
Cc: richard.henderson@linaro.org, philmd@linaro.org,
	qemu-arm@nongnu.org, qemu-devel@nongnu.org,
	alex.bennee@linaro.org
Subject: Re: [PATCH v3 09/26] target/arm/kvm-rme: Initialize Realm memory
Date: Tue, 4 Feb 2025 15:30:00 +1000	[thread overview]
Message-ID: <91b825c4-462f-4663-8412-effa84c0863d@redhat.com> (raw)
In-Reply-To: <20241125195626.856992-11-jean-philippe@linaro.org>

On 11/26/24 5:56 AM, Jean-Philippe Brucker wrote:
> Initialize the IPA state of RAM. Collect the images copied into guest
> RAM into a sorted list, and issue POPULATE_REALM KVM ioctls once we've
> created the Realm Descriptor. The images are part of the Realm Initial
> Measurement.
> 
> Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
> ---
> v2->v3: RIPAS is now initialized separately
> ---
>   target/arm/kvm_arm.h |  14 +++++
>   target/arm/kvm-rme.c | 128 +++++++++++++++++++++++++++++++++++++++++++
>   2 files changed, 142 insertions(+)
> 
> diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h
> index 8b52a881b0..67db09a424 100644
> --- a/target/arm/kvm_arm.h
> +++ b/target/arm/kvm_arm.h
> @@ -255,6 +255,16 @@ int kvm_arm_rme_vm_type(MachineState *ms);
>    */
>   int kvm_arm_rme_vcpu_init(CPUState *cs);
>   
> +/*
> + * kvm_arm_rme_init_guest_ram
> + * @base: base address of RAM
> + * @size: size of RAM
> + *
> + * If the user requested a Realm, set the base and size of guest RAM, in order
> + * to initialize the Realm IPA space.
> + */
> +void kvm_arm_rme_init_guest_ram(hwaddr base, size_t size);
> +
>   #else
>   
>   /*
> @@ -281,6 +291,10 @@ static inline bool kvm_arm_mte_supported(void)
>       return false;
>   }
>   
> +static inline void kvm_arm_rme_init_guest_ram(hwaddr base, size_t size)
> +{
> +}
> +
>   /*
>    * These functions should never actually be called without KVM support.
>    */
> diff --git a/target/arm/kvm-rme.c b/target/arm/kvm-rme.c
> index e3cc37538a..83a29421df 100644
> --- a/target/arm/kvm-rme.c
> +++ b/target/arm/kvm-rme.c
> @@ -9,6 +9,7 @@
>   #include "exec/confidential-guest-support.h"
>   #include "hw/boards.h"
>   #include "hw/core/cpu.h"
> +#include "hw/loader.h"
>   #include "kvm_arm.h"
>   #include "migration/blocker.h"
>   #include "qapi/error.h"
> @@ -20,16 +21,85 @@
>   #define TYPE_RME_GUEST "rme-guest"
>   OBJECT_DECLARE_SIMPLE_TYPE(RmeGuest, RME_GUEST)
>   
> +#define RME_PAGE_SIZE qemu_real_host_page_size()
> +
>   struct RmeGuest {
>       ConfidentialGuestSupport parent_obj;
> +    Notifier rom_load_notifier;
> +    GSList *ram_regions;
> +
> +    hwaddr ram_base;
> +    size_t ram_size;
>   };
>   

s/size_t/hwaddr. To be consistent with RmeRamRegion, we may reuse
it like below.

struct RmeGuest {
     :
     GSlist *populate_ram_regions;
     RmeRamRegion init_ram_region;
};

>   OBJECT_DEFINE_SIMPLE_TYPE_WITH_INTERFACES(RmeGuest, rme_guest, RME_GUEST,
>                                             CONFIDENTIAL_GUEST_SUPPORT,
>                                             { TYPE_USER_CREATABLE }, { })
>   
> +typedef struct {
> +    hwaddr base;
> +    hwaddr size;
> +} RmeRamRegion;
> +
>   static RmeGuest *rme_guest;
>   
> +static int rme_init_ram(hwaddr base, size_t size, Error **errp)
> +{
> +    int ret;
> +    uint64_t start = QEMU_ALIGN_DOWN(base, RME_PAGE_SIZE);
> +    uint64_t end = QEMU_ALIGN_UP(base + size, RME_PAGE_SIZE);
> +    struct kvm_cap_arm_rme_init_ipa_args init_args = {
> +        .init_ipa_base = start,
> +        .init_ipa_size = end - start,
> +    };
> +
> +    ret = kvm_vm_enable_cap(kvm_state, KVM_CAP_ARM_RME, 0,
> +                            KVM_CAP_ARM_RME_INIT_IPA_REALM,
> +                            (intptr_t)&init_args);
> +    if (ret) {
> +        error_setg_errno(errp, -ret,
> +                         "failed to init RAM [0x%"HWADDR_PRIx", 0x%"HWADDR_PRIx")",
                                                      ^^^^^^^^^^        ^^^^^^^^^^^
The type for 'start' and 'end' would be 'hwaddr'.

> +                         start, end);
> +    }
> +
> +    return ret;
> +}
> +
> +static int rme_populate_range(hwaddr base, size_t size, bool measure,
> +                              Error **errp)
> +{
> +    int ret;
> +    uint64_t start = QEMU_ALIGN_DOWN(base, RME_PAGE_SIZE);
> +    uint64_t end = QEMU_ALIGN_UP(base + size, RME_PAGE_SIZE);
> +    struct kvm_cap_arm_rme_populate_realm_args populate_args = {
> +        .populate_ipa_base = start,
> +        .populate_ipa_size = end - start,
> +        .flags = measure ? KVM_ARM_RME_POPULATE_FLAGS_MEASURE : 0,
> +    };
> +
> +    ret = kvm_vm_enable_cap(kvm_state, KVM_CAP_ARM_RME, 0,
> +                            KVM_CAP_ARM_RME_POPULATE_REALM,
> +                            (intptr_t)&populate_args);
> +    if (ret) {
> +        error_setg_errno(errp, -ret,
> +                   "failed to populate realm [0x%"HWADDR_PRIx", 0x%"HWADDR_PRIx")",
> +                   start, end);
> +    }
> +    return ret;
> +}
> +
> +static void rme_populate_ram_region(gpointer data, gpointer err)
> +{
> +    Error **errp = err;
> +    const RmeRamRegion *region = data;
> +
> +    if (*errp) {
> +        return;
> +    }
> +
> +    rme_populate_range(region->base, region->size, /* measure */ true, errp);
> +}
> +
>   static int rme_init_cpus(Error **errp)
>   {
>       int ret;
> @@ -60,6 +130,16 @@ static int rme_create_realm(Error **errp)
>           return -1;
>       }
>   
> +    if (rme_init_ram(rme_guest->ram_base, rme_guest->ram_size, errp)) {
> +        return -1;
> +    }
> +
> +    g_slist_foreach(rme_guest->ram_regions, rme_populate_ram_region, errp);
> +    g_slist_free_full(g_steal_pointer(&rme_guest->ram_regions), g_free);
> +    if (*errp) {
> +        return -1;
> +    }
> +
>       if (rme_init_cpus(errp)) {
>           return -1;
>       }
> @@ -105,6 +185,43 @@ static void rme_guest_finalize(Object *obj)
>   {
>   }
>   
> +static gint rme_compare_ram_regions(gconstpointer a, gconstpointer b)
> +{
> +        const RmeRamRegion *ra = a;
> +        const RmeRamRegion *rb = b;
> +
> +        g_assert(ra->base != rb->base);
> +        return ra->base < rb->base ? -1 : 1;
> +}
> +
> +static void rme_rom_load_notify(Notifier *notifier, void *data)
> +{
> +    RmeRamRegion *region;
> +    RomLoaderNotify *rom = data;
> +
> +    if (rom->addr == -1) {
> +        /*
> +         * These blobs (ACPI tables) are not loaded into guest RAM at reset.
> +         * Instead the firmware will load them via fw_cfg and measure them
> +         * itself.
> +         */
> +        return;
> +    }
> +
> +    region = g_new0(RmeRamRegion, 1);
> +    region->base = rom->addr;
> +    region->size = rom->len;
> +
> +    /*
> +     * The Realm Initial Measurement (RIM) depends on the order in which we
> +     * initialize and populate the RAM regions. To help a verifier
> +     * independently calculate the RIM, sort regions by GPA.
> +     */
> +    rme_guest->ram_regions = g_slist_insert_sorted(rme_guest->ram_regions,
> +                                                   region,
> +                                                   rme_compare_ram_regions);
> +}
> +
>   int kvm_arm_rme_init(MachineState *ms)
>   {
>       static Error *rme_mig_blocker;
> @@ -132,11 +249,22 @@ int kvm_arm_rme_init(MachineState *ms)
>        */
>       qemu_add_vm_change_state_handler(rme_vm_state_change, NULL);
>   
> +    rme_guest->rom_load_notifier.notify = rme_rom_load_notify;
> +    rom_add_load_notifier(&rme_guest->rom_load_notifier);
> +
>       cgs->require_guest_memfd = true;
>       cgs->ready = true;
>       return 0;
>   }
>   
> +void kvm_arm_rme_init_guest_ram(hwaddr base, size_t size)
> +{
> +    if (rme_guest) {
> +        rme_guest->ram_base = base;
> +        rme_guest->ram_size = size;
> +    }
> +}
> +
>   int kvm_arm_rme_vcpu_init(CPUState *cs)
>   {
>       ARMCPU *cpu = ARM_CPU(cs);

Thanks,
Gavin



  reply	other threads:[~2025-02-04  5:31 UTC|newest]

Thread overview: 71+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-11-25 19:55 [PATCH v3 00/26] arm: Run Arm CCA VMs with KVM Jean-Philippe Brucker
2024-11-25 19:56 ` [PATCH v3 01/26] kvm: Merge kvm_check_extension() and kvm_vm_check_extension() Jean-Philippe Brucker
2024-11-26 12:29   ` Daniel P. Berrangé
2024-12-04 19:07     ` Jean-Philippe Brucker
2024-11-25 19:56 ` [PATCH v3 02/26] target/arm: Add confidential guest support Jean-Philippe Brucker
2024-11-26 12:37   ` Daniel P. Berrangé
2024-12-04 19:07     ` Jean-Philippe Brucker
2024-11-25 19:56 ` [PATCH v3 03/26] target/arm/kvm: Return immediately on error in kvm_arch_init() Jean-Philippe Brucker
2024-12-05 21:47   ` Philippe Mathieu-Daudé
2024-12-10 19:06     ` Jean-Philippe Brucker
2024-11-25 19:56 ` [PATCH v3 04/26] target/arm/kvm-rme: Initialize realm Jean-Philippe Brucker
2024-11-25 19:56 ` [PATCH v3 05/26] target/arm/kvm: Split kvm_arch_get/put_registers Jean-Philippe Brucker
2024-11-25 19:56 ` [PATCH v3 06/26] target/arm/kvm-rme: Initialize vCPU Jean-Philippe Brucker
2025-02-04  5:02   ` Gavin Shan
2025-02-07 15:56     ` Jean-Philippe Brucker
2024-11-25 19:56 ` [PATCH v3 07/26] target/arm/kvm: Create scratch VM as Realm if necessary Jean-Philippe Brucker
2024-11-25 19:56 ` [PATCH v3 08/26] hw/core/loader: Add ROM loader notifier Jean-Philippe Brucker
2024-12-05 21:59   ` Philippe Mathieu-Daudé
2024-12-10 19:07     ` Jean-Philippe Brucker
2025-02-04  5:33   ` Gavin Shan
2025-02-07 15:57     ` Jean-Philippe Brucker
2024-11-25 19:56 ` [PATCH v3 09/26] target/arm/kvm-rme: Initialize Realm memory Jean-Philippe Brucker
2025-02-04  5:30   ` Gavin Shan [this message]
2025-02-07 15:59     ` Jean-Philippe Brucker
2024-11-25 19:56 ` [PATCH v3 10/26] target/arm/kvm-rme: Add Realm Personalization Value parameter Jean-Philippe Brucker
2024-11-26  7:20   ` Markus Armbruster
2024-11-26 12:47     ` Daniel P. Berrangé
2024-12-04 19:11       ` Jean-Philippe Brucker
2024-12-04 19:10     ` Jean-Philippe Brucker
2024-11-25 19:56 ` [PATCH v3 11/26] target/arm/kvm-rme: Add measurement algorithm property Jean-Philippe Brucker
2024-11-26 12:57   ` Daniel P. Berrangé
2024-11-26 15:11     ` Markus Armbruster
2024-11-26 15:17       ` Daniel P. Berrangé
2024-11-25 19:56 ` [PATCH v3 12/26] target/arm/cpu: Set number of breakpoints and watchpoints in KVM Jean-Philippe Brucker
2024-11-25 19:56 ` [PATCH v3 13/26] target/arm/cpu: Set number of PMU counters " Jean-Philippe Brucker
2024-11-25 19:56 ` [PATCH v3 14/26] target/arm/cpu: Inform about reading confidential CPU registers Jean-Philippe Brucker
2024-11-25 19:56 ` [PATCH v3 15/26] hw/arm/virt: Add support for Arm RME Jean-Philippe Brucker
2024-11-25 19:56 ` [PATCH v3 16/26] hw/arm/virt: Disable DTB randomness for confidential VMs Jean-Philippe Brucker
2024-12-05 22:03   ` Philippe Mathieu-Daudé
2024-11-25 19:56 ` [PATCH v3 17/26] hw/arm/virt: Reserve one bit of guest-physical address for RME Jean-Philippe Brucker
2024-12-13 12:03   ` Gavin Shan
2025-01-22 14:56     ` Jean-Philippe Brucker
2024-11-25 19:56 ` [PATCH v3 18/26] hw/arm/boot: Mark all guest memory as RIPAS_RAM Jean-Philippe Brucker
2025-02-04  7:27   ` Gavin Shan
2025-02-07 16:02     ` Jean-Philippe Brucker
2024-11-25 19:56 ` [PATCH v3 19/26] hw/arm/virt: Move virt_flash_create() to machvirt_init() Jean-Philippe Brucker
2024-11-25 19:56 ` [PATCH v3 20/26] hw/arm/virt: Use RAM instead of flash for confidential guest firmware Jean-Philippe Brucker
2024-11-25 19:56 ` [RFC PATCH v3 21/26] hw/arm/boot: Load DTB as is for confidential VMs Jean-Philippe Brucker
2024-11-25 19:56 ` [RFC PATCH v3 22/26] hw/arm/boot: Skip bootloader for confidential guests Jean-Philippe Brucker
2024-11-25 19:56 ` [RFC PATCH v3 23/26] hw/tpm: Add TPM event log Jean-Philippe Brucker
2024-12-05 22:13   ` Philippe Mathieu-Daudé
2024-12-09 22:34   ` Stefan Berger
2024-12-13 14:31     ` Jean-Philippe Brucker
2024-11-25 19:56 ` [RFC PATCH v3 24/26] hw/core/loader: Add fields to RomLoaderNotify Jean-Philippe Brucker
2024-12-05 22:21   ` Philippe Mathieu-Daudé
2024-12-10 19:04     ` Jean-Philippe Brucker
2024-11-25 19:56 ` [RFC PATCH v3 25/26] target/arm/kvm-rme: Add measurement log Jean-Philippe Brucker
2024-11-25 22:23   ` Stefan Berger
2024-11-26 13:45     ` Daniel P. Berrangé
2024-11-26 16:21       ` Jean-Philippe Brucker
2024-12-02 15:58         ` Stefan Berger
2024-12-05 12:33           ` Jean-Philippe Brucker
2024-12-09 20:22             ` Stefan Berger
2024-12-09 22:08   ` Stefan Berger
2024-12-13 14:21     ` Jean-Philippe Brucker
2024-12-13 16:51       ` Stefan Berger
2024-11-25 19:56 ` [RFC PATCH v3 26/26] hw/arm/virt: Add measurement log for confidential boot Jean-Philippe Brucker
2024-12-05 22:23   ` Philippe Mathieu-Daudé
2024-12-10 19:05     ` Jean-Philippe Brucker
2024-12-11  3:01 ` [PATCH v3 00/26] arm: Run Arm CCA VMs with KVM Gavin Shan
2024-12-11  8:01   ` Gavin Shan

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=91b825c4-462f-4663-8412-effa84c0863d@redhat.com \
    --to=gshan@redhat.com \
    --cc=alex.bennee@linaro.org \
    --cc=jean-philippe@linaro.org \
    --cc=peter.maydell@linaro.org \
    --cc=philmd@linaro.org \
    --cc=qemu-arm@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    --cc=richard.henderson@linaro.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).