From patchwork Mon Nov 25 19:56:00 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Philippe Brucker X-Patchwork-Id: 13885225 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 9BEFCD59D67 for ; Mon, 25 Nov 2024 20:02:12 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tFfF7-00051m-Vl; Mon, 25 Nov 2024 14:59:34 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tFfF6-00050g-5s for qemu-devel@nongnu.org; Mon, 25 Nov 2024 14:59:32 -0500 Received: from mail-wr1-x435.google.com ([2a00:1450:4864:20::435]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1tFfF1-0004ks-6y for qemu-devel@nongnu.org; Mon, 25 Nov 2024 14:59:31 -0500 Received: by mail-wr1-x435.google.com with SMTP id ffacd0b85a97d-382296631f1so3850003f8f.3 for ; Mon, 25 Nov 2024 11:59:26 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1732564765; x=1733169565; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=lPWuRq4ZMsQxJVcTsJdLWctdtR5b8av26RnGMZkAnrQ=; b=VqVZbsVoaRPDG+wGrrmfXwjWPrVwRHV9B6rs++XhvOzsNUTYj/fmqHYhkYIG+H1fGp p5O8xD4imXJh6AubO6GR+2LToWlJ82TpWOMkw5BgBbhWDMHHMjf2e5Yn4GPj/lQZPU+q GxgN2tqCaS7UBvYtz2U0M/N+VXzRvYDh4NC6o35Dwfsu0OE6WQChdJK6/2iXvziiZhXG QVs9Thf+aSGiNgEJC5CR0VR/2IEvatzBnr20pc/87YqaGYBrLtcOtiMu9gofCptQWqsc TgkzgMul1ZhHAQbSnGLer1UcENTJ8UY9qa6Szz3JT7aTSDHcVAmrimhebUzRY2oSxWq+ i1hQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1732564765; x=1733169565; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=lPWuRq4ZMsQxJVcTsJdLWctdtR5b8av26RnGMZkAnrQ=; b=t7Ps8J+MG00K729uGIjGet8dP+Uyc9MU9CZPMc2w5Zb/pQ51Bvroi19lclKgclmq78 aoDYPB9z3axhwsKQyuCRl/xEkJIMPxRZUQpXBdswsT8h26OQ7Q7oqQHRx1vCnnQOXDgm EXrZn5pBQlYpsLx5NRtnZjXjvXBybR+hh/jI8GAtHQUqiDXMLevBoylDqJoMQcOobrxt 6D8t6GNHEAfbzQQfLjZq0CBY/sXUJDujULW+k9hCZFEqflq78Zjx2z5GGGQnW1tnrOr7 18EP+POI5h5A85xpxbkCIvdjfsAuIjrBxbLznSz54kFDhTSAsND2YZ5x1cX9N2VhO49r T4lg== X-Forwarded-Encrypted: i=1; AJvYcCXYNepoErMtVsIe5qet0XfZM2iQvmbb5mPPrGIfSNkJ0kReYGNy6UTwCrJJL2IdwC/RyzQn4jmBRhGy@nongnu.org X-Gm-Message-State: AOJu0Yw2gln7qBzVM3Xoi7wMKg5+aTekif2x3yfCsqFNAzh0+GRSWyld c2rR68xLGn/a53GTrW17OnbJPhVB4NdKr5pN7CL6Q+uMN0j0zzObggwIJ1QxM5A= X-Gm-Gg: ASbGnct3hlMEutKkbAQs95KbMBfLoTwZNbFQ/N1tSXf2vt3EBZdDoTJcmSFl8ZQYn9Z +72/ERcPxXYOfsX3v2b2hULv4/5Y0UjHHBkEI56T+NBXtGA4H/10O+B1ZyZOVQwwwdTVl6OI0FE vBY+HODBfOUZyrmxfYVeHEpha3+kpkygkvGlJLiL2+j/mWEMJEjDLpqLLpRpz5JfVY9tT3NpUtH f2V3grZTfkR9bpRR7fbNdElZsoZ1+K46QkACqDpAToIgtX7QgsFC45dJwh+InGSmqXW X-Google-Smtp-Source: AGHT+IGlrn69zbFsAPm8N4oXGiZ1003KdIY3nIYvAHAfbGUJAyjEgBCTsF6eSMRF+mg0TiybTp9glA== X-Received: by 2002:a05:6000:4026:b0:382:4f68:1f63 with SMTP id ffacd0b85a97d-38260b455cfmr12925648f8f.7.1732564765127; Mon, 25 Nov 2024 11:59:25 -0800 (PST) Received: from localhost.localdomain ([2.221.137.100]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3825fd0fbdcsm11237971f8f.109.2024.11.25.11.59.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 25 Nov 2024 11:59:24 -0800 (PST) From: Jean-Philippe Brucker To: peter.maydell@linaro.org Cc: richard.henderson@linaro.org, philmd@linaro.org, qemu-arm@nongnu.org, qemu-devel@nongnu.org, alex.bennee@linaro.org, Jean-Philippe Brucker , Marcelo Tosatti , Nicholas Piggin , Daniel Henrique Barboza , qemu-ppc@nongnu.org, Cornelia Huck Subject: [PATCH v3 01/26] kvm: Merge kvm_check_extension() and kvm_vm_check_extension() Date: Mon, 25 Nov 2024 19:56:00 +0000 Message-ID: <20241125195626.856992-3-jean-philippe@linaro.org> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241125195626.856992-2-jean-philippe@linaro.org> References: <20241125195626.856992-2-jean-philippe@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::435; envelope-from=jean-philippe@linaro.org; helo=mail-wr1-x435.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org The KVM_CHECK_EXTENSION ioctl can be issued either on the global fd (/dev/kvm), or on the VM fd obtained with KVM_CREATE_VM. For most extensions, KVM returns the same value with either method, but for some of them it can refine the returned value depending on the VM type. The KVM documentation [1] advises to use the VM fd: Based on their initialization different VMs may have different capabilities. It is thus encouraged to use the vm ioctl to query for capabilities (available with KVM_CAP_CHECK_EXTENSION_VM on the vm fd) Ongoing work on Arm confidential VMs confirms this, as some capabilities become unavailable to confidential VMs, requiring changes in QEMU to use kvm_vm_check_extension() instead of kvm_check_extension() [2]. Rather than changing each check one by one, change kvm_check_extension() to always issue the ioctl on the VM fd when available, and remove kvm_vm_check_extension(). Fall back to the global fd when the VM check is unavailable: * Ancient kernels do not support KVM_CHECK_EXTENSION on the VM fd, since it was added by commit 92b591a4c46b ("KVM: Allow KVM_CHECK_EXTENSION on the vm fd") in Linux 3.17 [3]. Support for Linux 3.16 ended in June 2020, but there may still be old images around. * A couple of calls must be issued before the VM fd is available, since they determine the VM type: KVM_CAP_MIPS_VZ and KVM_CAP_ARM_VM_IPA_SIZE Does any user actually depend on the check being done on the global fd instead of the VM fd? I surveyed all cases where KVM presently returns different values depending on the query method. Luckily QEMU already calls kvm_vm_check_extension() for most of those. Only three of them are ambiguous, because currently done on the global fd: * KVM_CAP_MAX_VCPUS and KVM_CAP_MAX_VCPU_ID on Arm, changes value if the user requests a vGIC different from the default. But QEMU queries this before vGIC configuration, so the reported value will be the same. * KVM_CAP_SW_TLB on PPC. When issued on the global fd, returns false if the kvm-hv module is loaded; when issued on the VM fd, returns false only if the VM type is HV instead of PR. If this returns false, then QEMU will fail to initialize a BOOKE206 MMU model. So this patch supposedly improves things, as it allows to run this type of vCPU even when both KVM modules are loaded. * KVM_CAP_PPC_SECURE_GUEST. Similarly, doing this check on a VM fd refines the returned value, and ensures that SVM is actually supported. Since QEMU follows the check with kvm_vm_enable_cap(), this patch should only provide better error reporting. [1] https://www.kernel.org/doc/html/latest/virt/kvm/api.html#kvm-check-extension [2] https://lore.kernel.org/kvm/875ybi0ytc.fsf@redhat.com/ [3] https://github.com/torvalds/linux/commit/92b591a4c46b Cc: Marcelo Tosatti Cc: Nicholas Piggin Cc: Daniel Henrique Barboza Cc: qemu-ppc@nongnu.org Suggested-by: Cornelia Huck Signed-off-by: Jean-Philippe Brucker --- include/sysemu/kvm.h | 2 -- include/sysemu/kvm_int.h | 1 + accel/kvm/kvm-all.c | 41 +++++++++++++++++++--------------------- target/arm/kvm.c | 2 +- target/i386/kvm/kvm.c | 6 +++--- target/ppc/kvm.c | 36 +++++++++++++++++------------------ 6 files changed, 42 insertions(+), 46 deletions(-) diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h index c3a60b2890..63c96d0096 100644 --- a/include/sysemu/kvm.h +++ b/include/sysemu/kvm.h @@ -437,8 +437,6 @@ bool kvm_arch_stop_on_emulation_error(CPUState *cpu); int kvm_check_extension(KVMState *s, unsigned int extension); -int kvm_vm_check_extension(KVMState *s, unsigned int extension); - #define kvm_vm_enable_cap(s, capability, cap_flags, ...) \ ({ \ struct kvm_enable_cap cap = { \ diff --git a/include/sysemu/kvm_int.h b/include/sysemu/kvm_int.h index a1e72763da..cb38085d54 100644 --- a/include/sysemu/kvm_int.h +++ b/include/sysemu/kvm_int.h @@ -166,6 +166,7 @@ struct KVMState uint16_t xen_gnttab_max_frames; uint16_t xen_evtchn_max_pirq; char *device; + bool check_extension_vm; }; void kvm_memory_listener_register(KVMState *s, KVMMemoryListener *kml, diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c index 801cff16a5..7ea016d598 100644 --- a/accel/kvm/kvm-all.c +++ b/accel/kvm/kvm-all.c @@ -1238,7 +1238,11 @@ int kvm_check_extension(KVMState *s, unsigned int extension) { int ret; - ret = kvm_ioctl(s, KVM_CHECK_EXTENSION, extension); + if (!s->check_extension_vm) { + ret = kvm_ioctl(s, KVM_CHECK_EXTENSION, extension); + } else { + ret = kvm_vm_ioctl(s, KVM_CHECK_EXTENSION, extension); + } if (ret < 0) { ret = 0; } @@ -1246,19 +1250,6 @@ int kvm_check_extension(KVMState *s, unsigned int extension) return ret; } -int kvm_vm_check_extension(KVMState *s, unsigned int extension) -{ - int ret; - - ret = kvm_vm_ioctl(s, KVM_CHECK_EXTENSION, extension); - if (ret < 0) { - /* VM wide version not implemented, use global one instead */ - ret = kvm_check_extension(s, extension); - } - - return ret; -} - /* * We track the poisoned pages to be able to: * - replace them on VM reset @@ -1622,10 +1613,10 @@ static int kvm_dirty_ring_init(KVMState *s) * Read the max supported pages. Fall back to dirty logging mode * if the dirty ring isn't supported. */ - ret = kvm_vm_check_extension(s, capability); + ret = kvm_check_extension(s, capability); if (ret <= 0) { capability = KVM_CAP_DIRTY_LOG_RING_ACQ_REL; - ret = kvm_vm_check_extension(s, capability); + ret = kvm_check_extension(s, capability); } if (ret <= 0) { @@ -1648,7 +1639,7 @@ static int kvm_dirty_ring_init(KVMState *s) } /* Enable the backup bitmap if it is supported */ - ret = kvm_vm_check_extension(s, KVM_CAP_DIRTY_LOG_RING_WITH_BITMAP); + ret = kvm_check_extension(s, KVM_CAP_DIRTY_LOG_RING_WITH_BITMAP); if (ret > 0) { ret = kvm_vm_enable_cap(s, KVM_CAP_DIRTY_LOG_RING_WITH_BITMAP, 0); if (ret) { @@ -2404,7 +2395,7 @@ static void kvm_irqchip_create(KVMState *s) */ static int kvm_recommended_vcpus(KVMState *s) { - int ret = kvm_vm_check_extension(s, KVM_CAP_NR_VCPUS); + int ret = kvm_check_extension(s, KVM_CAP_NR_VCPUS); return (ret) ? ret : 4; } @@ -2625,7 +2616,12 @@ static int kvm_init(MachineState *ms) s->vmfd = ret; - s->nr_as = kvm_vm_check_extension(s, KVM_CAP_MULTI_ADDRESS_SPACE); + ret = kvm_vm_ioctl(s, KVM_CHECK_EXTENSION, KVM_CAP_CHECK_EXTENSION_VM); + if (ret > 0) { + s->check_extension_vm = true; + } + + s->nr_as = kvm_check_extension(s, KVM_CAP_MULTI_ADDRESS_SPACE); if (s->nr_as <= 1) { s->nr_as = 1; } @@ -2683,7 +2679,7 @@ static int kvm_init(MachineState *ms) } kvm_readonly_mem_allowed = - (kvm_vm_check_extension(s, KVM_CAP_READONLY_MEM) > 0); + (kvm_check_extension(s, KVM_CAP_READONLY_MEM) > 0); kvm_resamplefds_allowed = (kvm_check_extension(s, KVM_CAP_IRQFD_RESAMPLE) > 0); @@ -2717,7 +2713,8 @@ static int kvm_init(MachineState *ms) goto err; } - kvm_supported_memory_attributes = kvm_vm_check_extension(s, KVM_CAP_MEMORY_ATTRIBUTES); + kvm_supported_memory_attributes = + kvm_check_extension(s, KVM_CAP_MEMORY_ATTRIBUTES); kvm_guest_memfd_supported = kvm_check_extension(s, KVM_CAP_GUEST_MEMFD) && kvm_check_extension(s, KVM_CAP_USER_MEMORY2) && @@ -2743,7 +2740,7 @@ static int kvm_init(MachineState *ms) memory_listener_register(&kvm_io_listener, &address_space_io); - s->sync_mmu = !!kvm_vm_check_extension(kvm_state, KVM_CAP_SYNC_MMU); + s->sync_mmu = !!kvm_check_extension(kvm_state, KVM_CAP_SYNC_MMU); if (!s->sync_mmu) { ret = ram_block_discard_disable(true); assert(!ret); diff --git a/target/arm/kvm.c b/target/arm/kvm.c index 7b6812c0de..8bdf4abeb6 100644 --- a/target/arm/kvm.c +++ b/target/arm/kvm.c @@ -601,7 +601,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s) if (s->kvm_eager_split_size) { uint32_t sizes; - sizes = kvm_vm_check_extension(s, KVM_CAP_ARM_SUPPORTED_BLOCK_SIZES); + sizes = kvm_check_extension(s, KVM_CAP_ARM_SUPPORTED_BLOCK_SIZES); if (!sizes) { s->kvm_eager_split_size = 0; warn_report("Eager Page Split support not available"); diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c index 8e17942c3b..2f35e7468c 100644 --- a/target/i386/kvm/kvm.c +++ b/target/i386/kvm/kvm.c @@ -244,7 +244,7 @@ bool kvm_enable_hypercall(uint64_t enable_mask) bool kvm_has_smm(void) { - return kvm_vm_check_extension(kvm_state, KVM_CAP_X86_SMM); + return kvm_check_extension(kvm_state, KVM_CAP_X86_SMM); } bool kvm_has_adjust_clock_stable(void) @@ -3320,7 +3320,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s) } } - if (kvm_vm_check_extension(s, KVM_CAP_X86_USER_SPACE_MSR)) { + if (kvm_check_extension(s, KVM_CAP_X86_USER_SPACE_MSR)) { ret = kvm_vm_enable_userspace_msr(s); if (ret < 0) { return ret; @@ -5936,7 +5936,7 @@ static bool __kvm_enable_sgx_provisioning(KVMState *s) { int fd, ret; - if (!kvm_vm_check_extension(s, KVM_CAP_SGX_ATTRIBUTE)) { + if (!kvm_check_extension(s, KVM_CAP_SGX_ATTRIBUTE)) { return false; } diff --git a/target/ppc/kvm.c b/target/ppc/kvm.c index 3efc28f18b..8bcb0368ce 100644 --- a/target/ppc/kvm.c +++ b/target/ppc/kvm.c @@ -110,7 +110,7 @@ static uint32_t debug_inst_opcode; static bool kvmppc_is_pr(KVMState *ks) { /* Assume KVM-PR if the GET_PVINFO capability is available */ - return kvm_vm_check_extension(ks, KVM_CAP_PPC_GET_PVINFO) != 0; + return kvm_check_extension(ks, KVM_CAP_PPC_GET_PVINFO) != 0; } static int kvm_ppc_register_host_cpu_type(void); @@ -127,11 +127,11 @@ int kvm_arch_init(MachineState *ms, KVMState *s) cap_interrupt_unset = kvm_check_extension(s, KVM_CAP_PPC_UNSET_IRQ); cap_segstate = kvm_check_extension(s, KVM_CAP_PPC_SEGSTATE); cap_booke_sregs = kvm_check_extension(s, KVM_CAP_PPC_BOOKE_SREGS); - cap_ppc_smt_possible = kvm_vm_check_extension(s, KVM_CAP_PPC_SMT_POSSIBLE); + cap_ppc_smt_possible = kvm_check_extension(s, KVM_CAP_PPC_SMT_POSSIBLE); cap_spapr_tce = kvm_check_extension(s, KVM_CAP_SPAPR_TCE); cap_spapr_tce_64 = kvm_check_extension(s, KVM_CAP_SPAPR_TCE_64); cap_spapr_multitce = kvm_check_extension(s, KVM_CAP_SPAPR_MULTITCE); - cap_spapr_vfio = kvm_vm_check_extension(s, KVM_CAP_SPAPR_TCE_VFIO); + cap_spapr_vfio = kvm_check_extension(s, KVM_CAP_SPAPR_TCE_VFIO); cap_one_reg = kvm_check_extension(s, KVM_CAP_ONE_REG); cap_hior = kvm_check_extension(s, KVM_CAP_PPC_HIOR); cap_epr = kvm_check_extension(s, KVM_CAP_PPC_EPR); @@ -140,23 +140,23 @@ int kvm_arch_init(MachineState *ms, KVMState *s) * Note: we don't set cap_papr here, because this capability is * only activated after this by kvmppc_set_papr() */ - cap_htab_fd = kvm_vm_check_extension(s, KVM_CAP_PPC_HTAB_FD); + cap_htab_fd = kvm_check_extension(s, KVM_CAP_PPC_HTAB_FD); cap_fixup_hcalls = kvm_check_extension(s, KVM_CAP_PPC_FIXUP_HCALL); - cap_ppc_smt = kvm_vm_check_extension(s, KVM_CAP_PPC_SMT); - cap_htm = kvm_vm_check_extension(s, KVM_CAP_PPC_HTM); - cap_mmu_radix = kvm_vm_check_extension(s, KVM_CAP_PPC_MMU_RADIX); - cap_mmu_hash_v3 = kvm_vm_check_extension(s, KVM_CAP_PPC_MMU_HASH_V3); - cap_xive = kvm_vm_check_extension(s, KVM_CAP_PPC_IRQ_XIVE); - cap_resize_hpt = kvm_vm_check_extension(s, KVM_CAP_SPAPR_RESIZE_HPT); + cap_ppc_smt = kvm_check_extension(s, KVM_CAP_PPC_SMT); + cap_htm = kvm_check_extension(s, KVM_CAP_PPC_HTM); + cap_mmu_radix = kvm_check_extension(s, KVM_CAP_PPC_MMU_RADIX); + cap_mmu_hash_v3 = kvm_check_extension(s, KVM_CAP_PPC_MMU_HASH_V3); + cap_xive = kvm_check_extension(s, KVM_CAP_PPC_IRQ_XIVE); + cap_resize_hpt = kvm_check_extension(s, KVM_CAP_SPAPR_RESIZE_HPT); kvmppc_get_cpu_characteristics(s); - cap_ppc_nested_kvm_hv = kvm_vm_check_extension(s, KVM_CAP_PPC_NESTED_HV); + cap_ppc_nested_kvm_hv = kvm_check_extension(s, KVM_CAP_PPC_NESTED_HV); cap_large_decr = kvmppc_get_dec_bits(); - cap_fwnmi = kvm_vm_check_extension(s, KVM_CAP_PPC_FWNMI); + cap_fwnmi = kvm_check_extension(s, KVM_CAP_PPC_FWNMI); /* * Note: setting it to false because there is not such capability * in KVM at this moment. * - * TODO: call kvm_vm_check_extension() with the right capability + * TODO: call kvm_check_extension() with the right capability * after the kernel starts implementing it. */ cap_ppc_pvr_compat = false; @@ -166,8 +166,8 @@ int kvm_arch_init(MachineState *ms, KVMState *s) exit(1); } - cap_rpt_invalidate = kvm_vm_check_extension(s, KVM_CAP_PPC_RPT_INVALIDATE); - cap_ail_mode_3 = kvm_vm_check_extension(s, KVM_CAP_PPC_AIL_MODE_3); + cap_rpt_invalidate = kvm_check_extension(s, KVM_CAP_PPC_RPT_INVALIDATE); + cap_ail_mode_3 = kvm_check_extension(s, KVM_CAP_PPC_AIL_MODE_3); kvm_ppc_register_host_cpu_type(); return 0; @@ -1976,7 +1976,7 @@ static int kvmppc_get_pvinfo(CPUPPCState *env, struct kvm_ppc_pvinfo *pvinfo) { CPUState *cs = env_cpu(env); - if (kvm_vm_check_extension(cs->kvm_state, KVM_CAP_PPC_GET_PVINFO) && + if (kvm_check_extension(cs->kvm_state, KVM_CAP_PPC_GET_PVINFO) && !kvm_vm_ioctl(cs->kvm_state, KVM_PPC_GET_PVINFO, pvinfo)) { return 0; } @@ -2298,7 +2298,7 @@ int kvmppc_reset_htab(int shift_hint) /* Full emulation, tell caller to allocate htab itself */ return 0; } - if (kvm_vm_check_extension(kvm_state, KVM_CAP_PPC_ALLOC_HTAB)) { + if (kvm_check_extension(kvm_state, KVM_CAP_PPC_ALLOC_HTAB)) { int ret; ret = kvm_vm_ioctl(kvm_state, KVM_PPC_ALLOCATE_HTAB, &shift); if (ret == -ENOTTY) { @@ -2507,7 +2507,7 @@ static void kvmppc_get_cpu_characteristics(KVMState *s) cap_ppc_safe_bounds_check = 0; cap_ppc_safe_indirect_branch = 0; - ret = kvm_vm_check_extension(s, KVM_CAP_PPC_GET_CPU_CHAR); + ret = kvm_check_extension(s, KVM_CAP_PPC_GET_CPU_CHAR); if (!ret) { return; } From patchwork Mon Nov 25 19:56:01 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jean-Philippe Brucker X-Patchwork-Id: 13885218 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id EA311D59D68 for ; Mon, 25 Nov 2024 20:00:53 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tFfFB-00054K-9o; Mon, 25 Nov 2024 14:59:37 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tFfF9-00052p-Sb for qemu-devel@nongnu.org; Mon, 25 Nov 2024 14:59:35 -0500 Received: from mail-wr1-x430.google.com ([2a00:1450:4864:20::430]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1tFfF1-0004l5-9E for qemu-devel@nongnu.org; Mon, 25 Nov 2024 14:59:35 -0500 Received: by mail-wr1-x430.google.com with SMTP id ffacd0b85a97d-3823eb7ba72so3268774f8f.0 for ; Mon, 25 Nov 2024 11:59:26 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1732564766; x=1733169566; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=yDanRZ41COf9qTLckEjQq0Cl2uY26nz9MVJ4DyeUoVM=; b=VJHX0HGJZjNb/XMsFd5ekMy9rTvVVkt916sSD+zMBip8zyplIi6chAxbbfWv6uWbS1 0mang6Q9Yw3iBpZxiqnYjVIfl7OMZd0R+yHAbLM6TIERvaQXMfTPA2h5982rqyOxKFFf GY2BQwICkHiLwkMroRZtkqcdw97qLHKRaek/bkD53IT8YhT/gA04uwTWd38/VXWMVpwM JMV+oBx690NK32jXVZkPdSRFa5unx5pJOu6hDd2DtnVXWo0O7iit68v4fkaSA1rT1GUW qPNRX5+uDCfZS06F0r9NcfJbCDPbfq3srzq8fiJqMysu2EZ760voE+NMFaRUngRJWTVD FqZg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1732564766; x=1733169566; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=yDanRZ41COf9qTLckEjQq0Cl2uY26nz9MVJ4DyeUoVM=; b=Cg5UIzeezoE6ZS43LgUW4i2z8DQq8xZYEnIviKCNSVEmMWkTkYQz0JtE5fBlxpE82B flIR9PuMGDl4Tjo3DJtlTDI3iVG31/zvgyHy34V8f9V6w6iZigCE77+gc3tIvruEk83Y Sv7QzdgLqwZ0kDGObqnIYYpgWQFiJ65qXDWGc85OoVExU0xOiBvNvWFrf0o5IVIxzBFq zd/+F4k6L4N/OBRewX2YMgV8AVq6qv8zn2ES63eF86UR1iH79BZt4u2PFIRYU0+/2R2p UZWFjr+nETrTe5+gwy7H3n0e72ILtUn+gENg2cGB5UZMx2FvHcEbpykswOwTAl57QMLK zeLQ== X-Forwarded-Encrypted: i=1; AJvYcCVbZeZS3G6HDgB65j43YMfK4Q9cieLQ2w5TKi8DyTFpkifUCs+I16+G8YEa4mxMRf2MfedCPgg//6tI@nongnu.org X-Gm-Message-State: AOJu0Yx8XYiolIjRDaQN80PEyzvynPFwpuBfBgaXvNZnAPkI5J+MFvT0 X2UuP+5pRNLB3/IFg3Pe6GeeaMTdPRogalUJtoauhUFxuyM/onUPb8KiLqkIfBk= X-Gm-Gg: ASbGnct7YCDEi/cfGbn2ejSCTu4B4R1CqFQjKpOFuXxDkzNhs657UkKDn9Z+15FInyd 04wJYeQq19OSPu3VhHFargHNmKD+DnTTCW/M99C0xygYsCC36HkN6RiM1QF4XgMNBz5uN8ZsOwo gy0hiq6CLZ20LXXnuTE5v6R9RC+c28s9uR8TTDyg0MR/picpZKggjs3bEEsXlK2EaqIxhFm4bBV SmyhF9HRhLOWPB95tSzM97tdU+Si5qOEkouyYMbU7fynjJgAZbPlzR/QlX5OEYzrrOL X-Google-Smtp-Source: AGHT+IEKWiu9Gp+Iust03Qntq+lTTn6PE7oIa8qEmxB8CKAOsTRCh9uUchQpL9TfWU7/drGclc4GbQ== X-Received: by 2002:a05:6000:2d08:b0:382:50d9:bc7c with SMTP id ffacd0b85a97d-38260be6bfamr7331620f8f.58.1732564765799; Mon, 25 Nov 2024 11:59:25 -0800 (PST) Received: from localhost.localdomain ([2.221.137.100]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3825fd0fbdcsm11237971f8f.109.2024.11.25.11.59.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 25 Nov 2024 11:59:25 -0800 (PST) From: Jean-Philippe Brucker To: peter.maydell@linaro.org Cc: richard.henderson@linaro.org, philmd@linaro.org, qemu-arm@nongnu.org, qemu-devel@nongnu.org, alex.bennee@linaro.org, Jean-Philippe Brucker , Eric Blake , Markus Armbruster , =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= , Eduardo Habkost Subject: [PATCH v3 02/26] target/arm: Add confidential guest support Date: Mon, 25 Nov 2024 19:56:01 +0000 Message-ID: <20241125195626.856992-4-jean-philippe@linaro.org> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241125195626.856992-2-jean-philippe@linaro.org> References: <20241125195626.856992-2-jean-philippe@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::430; envelope-from=jean-philippe@linaro.org; helo=mail-wr1-x430.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Add a new RmeGuest object, inheriting from ConfidentialGuestSupport, to support the Arm Realm Management Extension (RME). It is instantiated by passing on the command-line: -M virt,confidential-guest-support= -object rme-guest,id=[,options...] This is only the skeleton. Support will be added in following patches. Cc: Eric Blake Cc: Markus Armbruster Cc: Daniel P. Berrangé Cc: Eduardo Habkost Acked-by: Markus Armbruster Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Richard Henderson Signed-off-by: Jean-Philippe Brucker --- v2->v3: remove some boilerplate with OBJECT_DEFINE_SIMPLE_TYPE_WITH_INTERFACES --- docs/system/confidential-guest-support.rst | 1 + target/arm/kvm-rme.c | 40 ++++++++++++++++++++++ target/arm/meson.build | 7 +++- 3 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 target/arm/kvm-rme.c diff --git a/docs/system/confidential-guest-support.rst b/docs/system/confidential-guest-support.rst index 0c490dbda2..acf46d8856 100644 --- a/docs/system/confidential-guest-support.rst +++ b/docs/system/confidential-guest-support.rst @@ -40,5 +40,6 @@ Currently supported confidential guest mechanisms are: * AMD Secure Encrypted Virtualization (SEV) (see :doc:`i386/amd-memory-encryption`) * POWER Protected Execution Facility (PEF) (see :ref:`power-papr-protected-execution-facility-pef`) * s390x Protected Virtualization (PV) (see :doc:`s390x/protvirt`) +* Arm Realm Management Extension (RME) Other mechanisms may be supported in future. diff --git a/target/arm/kvm-rme.c b/target/arm/kvm-rme.c new file mode 100644 index 0000000000..67909349c1 --- /dev/null +++ b/target/arm/kvm-rme.c @@ -0,0 +1,40 @@ +/* + * QEMU Arm RME support + * + * Copyright Linaro 2024 + */ + +#include "qemu/osdep.h" + +#include "exec/confidential-guest-support.h" +#include "hw/boards.h" +#include "hw/core/cpu.h" +#include "kvm_arm.h" +#include "migration/blocker.h" +#include "qapi/error.h" +#include "qom/object_interfaces.h" +#include "sysemu/kvm.h" +#include "sysemu/runstate.h" + +#define TYPE_RME_GUEST "rme-guest" +OBJECT_DECLARE_SIMPLE_TYPE(RmeGuest, RME_GUEST) + +struct RmeGuest { + ConfidentialGuestSupport parent_obj; +}; + +OBJECT_DEFINE_SIMPLE_TYPE_WITH_INTERFACES(RmeGuest, rme_guest, RME_GUEST, + CONFIDENTIAL_GUEST_SUPPORT, + { TYPE_USER_CREATABLE }, { }) + +static void rme_guest_class_init(ObjectClass *oc, void *data) +{ +} + +static void rme_guest_init(Object *obj) +{ +} + +static void rme_guest_finalize(Object *obj) +{ +} diff --git a/target/arm/meson.build b/target/arm/meson.build index 2e10464dbb..c610c078f7 100644 --- a/target/arm/meson.build +++ b/target/arm/meson.build @@ -8,7 +8,12 @@ arm_ss.add(files( )) arm_ss.add(zlib) -arm_ss.add(when: 'CONFIG_KVM', if_true: files('hyp_gdbstub.c', 'kvm.c'), if_false: files('kvm-stub.c')) +arm_ss.add(when: 'CONFIG_KVM', + if_true: files( + 'hyp_gdbstub.c', + 'kvm.c', + 'kvm-rme.c'), + if_false: files('kvm-stub.c')) arm_ss.add(when: 'CONFIG_HVF', if_true: files('hyp_gdbstub.c')) arm_ss.add(when: 'TARGET_AARCH64', if_true: files( From patchwork Mon Nov 25 19:56:02 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Philippe Brucker X-Patchwork-Id: 13885239 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id C6C36D59D69 for ; Mon, 25 Nov 2024 20:05:30 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tFfF8-00052W-Vo; Mon, 25 Nov 2024 14:59:35 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tFfF6-000514-L0 for qemu-devel@nongnu.org; Mon, 25 Nov 2024 14:59:32 -0500 Received: from mail-wm1-x336.google.com ([2a00:1450:4864:20::336]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1tFfF1-0004lJ-Oi for qemu-devel@nongnu.org; Mon, 25 Nov 2024 14:59:32 -0500 Received: by mail-wm1-x336.google.com with SMTP id 5b1f17b1804b1-43494a20379so17709955e9.0 for ; Mon, 25 Nov 2024 11:59:27 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1732564766; x=1733169566; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=AUUGPkOeOTTu2+NC5FrYwYu1VqmCribZfZ+rxUCPPlM=; b=AYELKALOpB+vT8qq4kgt2mXmKO/TBS3e7WBJ574fISxgduEip4MNXiSp7RhIqmfx5a 1+ZeQv+oL62ej32AXuYDKl+Pd/IveMf+VQa2A2d9mMXOHX0Ra85y4Pe3xq/DSZmd9iJU 0h2joaq/9LgWS4cDDgQI5+RJsgS+ZgqMArG4A1pkBzO4kNsUp9GFbYZZ+gTfBvknwugY 0uYXVA1uLxdFsPwsYH9NtIjcMCk+fyBhNdjx/r9Pq+QvT+JHHl2FfrmHswqTToYOIZn5 Bx3YCtzj95c6l0v17k8db7GgQcpt3TufOVv9tvEUN0dOm6ZlWCQRoYtZpFTDSRm0SrK9 ix6g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1732564766; x=1733169566; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=AUUGPkOeOTTu2+NC5FrYwYu1VqmCribZfZ+rxUCPPlM=; b=Vt/eX3FTFianrmlylkSDGK7Sbdffn2TFYxfS1HCJXTDOYDpR5tnyOxR+v0XcmVN/rC ZfEqTP7ZhBXgKicgcks+Av4Uf/v/b6gGy7QwjaYREfM7VFL/LtDayGQJlJ3TGay4VbLA mc4YEXbDo8hgkzLTH4J6ZiJOJ0WC4ZUJSzrouBVXhKSitoGXcZ5KO2bbrA6ywC8SBnBU +B3yyigRxLG8fnKn6mxhc8XgWxIgYpaZL6CTyKV+ulnHwxvEYIRKphh7ZZSIxhdQHMjC zefgtmLTKnMkl2MgQqpcofF+LBmFG4Ex4c8t2MgerTePkYybhKPLaCDnjEzDSmT7fksu qB/w== X-Forwarded-Encrypted: i=1; AJvYcCU2xFUKc8d2GQGpKZuHvShKXzwp3SZrNn0Hnscr7FcKcpfa2/4wbeax8iSig4xevT7M8x49M0KjjrY0@nongnu.org X-Gm-Message-State: AOJu0YzDDmovlOtQcNhxulE+V5UKfU9+yU7BvS0VYPYLOr1cqbR1Gc/c GFvkPsm6aUmm857c7RDG3pKadNXM9g7g4RnN30TS0zPWBhwuS+mu8HkuzoypWaM= X-Gm-Gg: ASbGncuEFUunXt1E8aCJoa6CeLEWOJFNQPH+gfghzN8sgPOqPVWwtmExVej22+wL04t c6SNP5hssMJRJfpj/s9020v/VfCFMaOb6zRdK1XV5RyR2YDaqvybKnwMNpgxebJ2ZCo6YJrIXxU rGajgNnDKpor4nHI3PvjiUKtad2AOo+mqCyo+j8UConHvrlGVYm7wYoK2zZz8yg1eYa0+3dfWn/ Mi7PlhGpCfEniFI2Ebr6eFwfZQNjd+xvOswtdO9ZVD+zL4VBrH2L+CKYkRtCQC4NDbz X-Google-Smtp-Source: AGHT+IEKfTHdZFW+oj4dYHwYt+075eZ/vDoe3cPOa5Tj6NfVEo8CowgGjm+2FvHfVf6gMGEwUzHcFw== X-Received: by 2002:a05:600c:3b25:b0:430:5760:2fe with SMTP id 5b1f17b1804b1-433ce4c2218mr111110665e9.22.1732564766349; Mon, 25 Nov 2024 11:59:26 -0800 (PST) Received: from localhost.localdomain ([2.221.137.100]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3825fd0fbdcsm11237971f8f.109.2024.11.25.11.59.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 25 Nov 2024 11:59:26 -0800 (PST) From: Jean-Philippe Brucker To: peter.maydell@linaro.org Cc: richard.henderson@linaro.org, philmd@linaro.org, qemu-arm@nongnu.org, qemu-devel@nongnu.org, alex.bennee@linaro.org, Jean-Philippe Brucker Subject: [PATCH v3 03/26] target/arm/kvm: Return immediately on error in kvm_arch_init() Date: Mon, 25 Nov 2024 19:56:02 +0000 Message-ID: <20241125195626.856992-5-jean-philippe@linaro.org> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241125195626.856992-2-jean-philippe@linaro.org> References: <20241125195626.856992-2-jean-philippe@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::336; envelope-from=jean-philippe@linaro.org; helo=mail-wm1-x336.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Returning an error to kvm_init() is fatal anyway, no need to continue the initialization. Signed-off-by: Jean-Philippe Brucker --- target/arm/kvm.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/target/arm/kvm.c b/target/arm/kvm.c index 8bdf4abeb6..95bcecf804 100644 --- a/target/arm/kvm.c +++ b/target/arm/kvm.c @@ -563,7 +563,7 @@ int kvm_arch_get_default_type(MachineState *ms) int kvm_arch_init(MachineState *ms, KVMState *s) { - int ret = 0; + int ret; /* For ARM interrupt delivery is always asynchronous, * whether we are using an in-kernel VGIC or not. */ @@ -585,7 +585,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s) !kvm_check_extension(s, KVM_CAP_ARM_IRQ_LINE_LAYOUT_2)) { error_report("Using more than 256 vcpus requires a host kernel " "with KVM_CAP_ARM_IRQ_LINE_LAYOUT_2"); - ret = -EINVAL; + return -EINVAL; } if (kvm_check_extension(s, KVM_CAP_ARM_NISV_TO_USER)) { @@ -607,13 +607,14 @@ int kvm_arch_init(MachineState *ms, KVMState *s) warn_report("Eager Page Split support not available"); } else if (!(s->kvm_eager_split_size & sizes)) { error_report("Eager Page Split requested chunk size not valid"); - ret = -EINVAL; + return -EINVAL; } else { ret = kvm_vm_enable_cap(s, KVM_CAP_ARM_EAGER_SPLIT_CHUNK_SIZE, 0, s->kvm_eager_split_size); if (ret < 0) { error_report("Enabling of Eager Page Split failed: %s", strerror(-ret)); + return ret; } } } @@ -626,7 +627,7 @@ int kvm_arch_init(MachineState *ms, KVMState *s) hw_breakpoints = g_array_sized_new(true, true, sizeof(HWBreakpoint), max_hw_bps); - return ret; + return 0; } unsigned long kvm_arch_vcpu_id(CPUState *cpu) From patchwork Mon Nov 25 19:56:03 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Philippe Brucker X-Patchwork-Id: 13885221 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id ECA3FD59D67 for ; Mon, 25 Nov 2024 20:01:40 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tFfFF-00058Y-Jy; Mon, 25 Nov 2024 14:59:41 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tFfFB-00054c-S4 for qemu-devel@nongnu.org; Mon, 25 Nov 2024 14:59:37 -0500 Received: from mail-wr1-x42d.google.com ([2a00:1450:4864:20::42d]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1tFfF4-0004ly-0o for qemu-devel@nongnu.org; Mon, 25 Nov 2024 14:59:37 -0500 Received: by mail-wr1-x42d.google.com with SMTP id ffacd0b85a97d-3824446d2bcso4300921f8f.2 for ; Mon, 25 Nov 2024 11:59:29 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1732564768; x=1733169568; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=y1yqlpej3WjW1JQDA6ksx54DWAhTx2FxYXSqrclmH28=; b=VfZ9MnM1GfBL5TzHBhsMp8SFlKTnEpX8aq8uZ/3GQRcL+9zU+vVfEKkizT0hS/3R0t yEbSBNATrlZyK9xTEIvxzLSriAM1EztFG8s0NJ3eTCJiWm/OvRFXtxaGkSqtMXWmA6ks gmP9rs5whUBQ++Bho4mBvgUtCVOsxca49FRPs5nlwqzUTEI4CG3coZqm7Ynz/SkJOvnE OSiFgbBE28lBkuxSmHymx0neYSI7tQDNSAagiK+Av+9rcr8Lns/QmOqaaLFlHyCipfx1 WGznofsvreDHtRRE0q6v8OWx5OyzC1FPUMtIx6Zj+t3gvbXjE6OOT1KsWTOiHrppZ4V+ cJ5A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1732564768; x=1733169568; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=y1yqlpej3WjW1JQDA6ksx54DWAhTx2FxYXSqrclmH28=; b=qOa8Ss5MuZJUNn+G5FuiURzjgn+62ndE77NWEJ/UNXCVrtr13ELspsHDgacj15xmzp B/7OrWibsUxh32/97LwBIxEymm6n5CsweRPavuoaTLxjkzwNOXREw16kQhgxL8BjGsXa JtFpt/vSdPy2GG/T7Pz4ap1kRWXmw9v3nxWQTqJtXzTI9ID9RAiOQkBSiL//eI6oUn2e yZITrlgKnWCeEgmFD4x1Lmay0jonUJ+BOnTND81yExL5cV2c/Ean1/dHTgebhU9N5GDF SPTt1gAmhdnCm9A/aI5uprQlxXIDWw+cgaBeZyR4mItVlQXyrj/c7vj8NLahnIT91t7m hGkA== X-Forwarded-Encrypted: i=1; AJvYcCWUqnHYHp0yXtrRBcUcVDozIkGBYJ0CZpAQEHANdeIfRm+ncrYFf7LGJ88zLo6rvqecWxg4jD8ErG/z@nongnu.org X-Gm-Message-State: AOJu0Yxd/Jy6vE/dhLMvUQn44MRz0tjVReC7exh0NZb4Bbh826F+/tXC Kr6UzJsNlvByW+QrvbUjlwecXqrAJw3CfNhq1mwAgs6mqU/KYF4jm3V27p5clJo= X-Gm-Gg: ASbGncs/VU/AZ9kUXpf3RJpYYcRfxEbUg1a0t9zmPoB9sUiRDsHa4DHgxLMGXLT74uV NLe6noOTddAGg2IMDIYq7aW+VbgWUBRE2bt2msHgVi2GGdoC/AlQKJYo2ofoYwVSQLWd9Y+yOMm dq9WFy/YORbgMP+OurUR+0J/7UDVsTntZBErrocDkWrLyx+kSNGm/njg5/o9tRC/lx+5Y9Ju3/l 34m+MOXpryL0Uk7KK/6TQP0fA2iUl2TJ/IP8M/7mmWrsKk/zRET6mScUWVyISx8h5j0 X-Google-Smtp-Source: AGHT+IFsIzPEH/whkFkArGEmVc/nnWnbFUS8SKjy/3ZNik9sJI/dbV0ygS/lbB2p3m1K4Zl/8as48w== X-Received: by 2002:a5d:47cc:0:b0:382:506b:f627 with SMTP id ffacd0b85a97d-38260bea7a0mr17079479f8f.57.1732564766896; Mon, 25 Nov 2024 11:59:26 -0800 (PST) Received: from localhost.localdomain ([2.221.137.100]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3825fd0fbdcsm11237971f8f.109.2024.11.25.11.59.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 25 Nov 2024 11:59:26 -0800 (PST) From: Jean-Philippe Brucker To: peter.maydell@linaro.org Cc: richard.henderson@linaro.org, philmd@linaro.org, qemu-arm@nongnu.org, qemu-devel@nongnu.org, alex.bennee@linaro.org, Jean-Philippe Brucker Subject: [PATCH v3 04/26] target/arm/kvm-rme: Initialize realm Date: Mon, 25 Nov 2024 19:56:03 +0000 Message-ID: <20241125195626.856992-6-jean-philippe@linaro.org> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241125195626.856992-2-jean-philippe@linaro.org> References: <20241125195626.856992-2-jean-philippe@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::42d; envelope-from=jean-philippe@linaro.org; helo=mail-wr1-x42d.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org The machine code calls kvm_arm_rme_vm_type() to get the VM flag and KVM calls kvm_arm_rme_init() to prepare for launching a Realm. Once VM creation is complete, create the Realm: * Create the realm descriptor, * load images into Realm RAM (in another patch), * finalize the REC (vCPU) after the registers are reset, * activate the realm, at which point the realm is sealed. Signed-off-by: Jean-Philippe Brucker --- v2->v3: * Cleaner error handling --- target/arm/kvm_arm.h | 39 ++++++++++++++++ target/arm/kvm-rme.c | 106 +++++++++++++++++++++++++++++++++++++++++++ target/arm/kvm.c | 9 +++- 3 files changed, 152 insertions(+), 2 deletions(-) diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h index 2e6b49bf13..9d6a89f9b1 100644 --- a/target/arm/kvm_arm.h +++ b/target/arm/kvm_arm.h @@ -153,6 +153,14 @@ void kvm_arm_set_cpu_features_from_host(ARMCPU *cpu); */ void kvm_arm_add_vcpu_properties(ARMCPU *cpu); +/** + * @cpu: The CPU object to finalize + * @feature: a KVM_ARM_VCPU_* feature + * + * Finalize the configuration of the given vcpu feature. + */ +int kvm_arm_vcpu_finalize(ARMCPU *cpu, int feature); + /** * kvm_arm_steal_time_finalize: * @cpu: ARMCPU for which to finalize kvm-steal-time @@ -221,6 +229,22 @@ int kvm_arm_set_irq(int cpu, int irqtype, int irq, int level); void kvm_arm_enable_mte(Object *cpuobj, Error **errp); +/** + * kvm_arm_rme_init + * @ms: the machine state + * + * Prepare the machine to be a Realm, if the user enabled it. + */ +int kvm_arm_rme_init(MachineState *ms); + +/** + * kvm_arm_rme_vm_type + * @ms: the machine state + * + * Returns the Realm KVM VM type if the user requested a Realm, 0 otherwise. + */ +int kvm_arm_rme_vm_type(MachineState *ms); + #else /* @@ -260,6 +284,11 @@ static inline void kvm_arm_add_vcpu_properties(ARMCPU *cpu) g_assert_not_reached(); } +static inline int kvm_arm_vcpu_finalize(ARMCPU *cpu, int feature) +{ + g_assert_not_reached(); +} + static inline int kvm_arm_get_max_vm_ipa_size(MachineState *ms, bool *fixed_ipa) { g_assert_not_reached(); @@ -300,6 +329,16 @@ static inline void kvm_arm_enable_mte(Object *cpuobj, Error **errp) g_assert_not_reached(); } +static inline int kvm_arm_rme_init(MachineState *ms) +{ + g_assert_not_reached(); +} + +static inline int kvm_arm_rme_vm_type(MachineState *ms) +{ + g_assert_not_reached(); +} + #endif #endif diff --git a/target/arm/kvm-rme.c b/target/arm/kvm-rme.c index 67909349c1..60d967a842 100644 --- a/target/arm/kvm-rme.c +++ b/target/arm/kvm-rme.c @@ -12,6 +12,7 @@ #include "kvm_arm.h" #include "migration/blocker.h" #include "qapi/error.h" +#include "qemu/error-report.h" #include "qom/object_interfaces.h" #include "sysemu/kvm.h" #include "sysemu/runstate.h" @@ -27,14 +28,119 @@ OBJECT_DEFINE_SIMPLE_TYPE_WITH_INTERFACES(RmeGuest, rme_guest, RME_GUEST, CONFIDENTIAL_GUEST_SUPPORT, { TYPE_USER_CREATABLE }, { }) +static RmeGuest *rme_guest; + +static int rme_init_cpus(Error **errp) +{ + int ret; + CPUState *cs; + + /* + * Now that do_cpu_reset() initialized the boot PC and + * kvm_cpu_synchronize_post_reset() registered it, we can finalize the REC. + */ + CPU_FOREACH(cs) { + ret = kvm_arm_vcpu_finalize(ARM_CPU(cs), KVM_ARM_VCPU_REC); + if (ret) { + error_setg_errno(errp, -ret, "failed to finalize vCPU"); + return ret; + } + } + return 0; +} + +static int rme_create_realm(Error **errp) +{ + int ret; + + ret = kvm_vm_enable_cap(kvm_state, KVM_CAP_ARM_RME, 0, + KVM_CAP_ARM_RME_CREATE_RD); + if (ret) { + error_setg_errno(errp, -ret, "failed to create Realm Descriptor"); + return -1; + } + + if (rme_init_cpus(errp)) { + return -1; + } + + ret = kvm_vm_enable_cap(kvm_state, KVM_CAP_ARM_RME, 0, + KVM_CAP_ARM_RME_ACTIVATE_REALM); + if (ret) { + error_setg_errno(errp, -ret, "failed to activate realm"); + return -1; + } + + kvm_mark_guest_state_protected(); + return 0; +} + +static void rme_vm_state_change(void *opaque, bool running, RunState state) +{ + Error *err = NULL; + + if (!running) { + return; + } + + if (rme_create_realm(&err)) { + error_propagate_prepend(&error_fatal, err, "RME: "); + } +} + static void rme_guest_class_init(ObjectClass *oc, void *data) { } static void rme_guest_init(Object *obj) { + if (rme_guest) { + error_report("a single instance of RmeGuest is supported"); + exit(1); + } + rme_guest = RME_GUEST(obj); } static void rme_guest_finalize(Object *obj) { } + +int kvm_arm_rme_init(MachineState *ms) +{ + static Error *rme_mig_blocker; + ConfidentialGuestSupport *cgs = ms->cgs; + + if (!rme_guest) { + return 0; + } + + if (!cgs) { + error_report("missing -machine confidential-guest-support parameter"); + return -EINVAL; + } + + if (!kvm_check_extension(kvm_state, KVM_CAP_ARM_RME)) { + return -ENODEV; + } + + error_setg(&rme_mig_blocker, "RME: migration is not implemented"); + migrate_add_blocker(&rme_mig_blocker, &error_fatal); + + /* + * The realm activation is done last, when the VM starts, after all images + * have been loaded and all vcpus finalized. + */ + qemu_add_vm_change_state_handler(rme_vm_state_change, NULL); + + cgs->require_guest_memfd = true; + cgs->ready = true; + return 0; +} + +int kvm_arm_rme_vm_type(MachineState *ms) +{ + if (rme_guest) { + return KVM_VM_TYPE_ARM_REALM; + } + return 0; +} diff --git a/target/arm/kvm.c b/target/arm/kvm.c index 95bcecf804..440c3ac8c6 100644 --- a/target/arm/kvm.c +++ b/target/arm/kvm.c @@ -95,7 +95,7 @@ static int kvm_arm_vcpu_init(ARMCPU *cpu) * * Returns: 0 if success else < 0 error code */ -static int kvm_arm_vcpu_finalize(ARMCPU *cpu, int feature) +int kvm_arm_vcpu_finalize(ARMCPU *cpu, int feature) { return kvm_vcpu_ioctl(CPU(cpu), KVM_ARM_VCPU_FINALIZE, &feature); } @@ -627,7 +627,12 @@ int kvm_arch_init(MachineState *ms, KVMState *s) hw_breakpoints = g_array_sized_new(true, true, sizeof(HWBreakpoint), max_hw_bps); - return 0; + ret = kvm_arm_rme_init(ms); + if (ret) { + error_report("Failed to enable RME: %s", strerror(-ret)); + } + + return ret; } unsigned long kvm_arch_vcpu_id(CPUState *cpu) From patchwork Mon Nov 25 19:56:04 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Philippe Brucker X-Patchwork-Id: 13885217 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id D7A1BD59D68 for ; Mon, 25 Nov 2024 20:00:28 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tFfF9-00052l-Sm; Mon, 25 Nov 2024 14:59:35 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tFfF7-00051a-Ef for qemu-devel@nongnu.org; Mon, 25 Nov 2024 14:59:33 -0500 Received: from mail-wm1-x32a.google.com ([2a00:1450:4864:20::32a]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1tFfF2-0004li-Vl for qemu-devel@nongnu.org; Mon, 25 Nov 2024 14:59:33 -0500 Received: by mail-wm1-x32a.google.com with SMTP id 5b1f17b1804b1-4349cc45219so16710815e9.3 for ; Mon, 25 Nov 2024 11:59:28 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1732564767; x=1733169567; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=eWjtUwTz+qxGQM43m+Z3dIisqsvdUtxVeJqucaNK404=; b=VaqGWztdmjGBnuY3B+g+bgbMKFRPI3+XgQ1yin5XCp1ScU4Nw1g2wpvyY7Q91lc62I Eyx61VE+q2UY7GBWhhiLG5rnkFcXSEKDSLQQvAWgMt9Z0hn8mxSLOUxNczGlNMLYETPx CauY52b6ktT9TdUixc+O/VHIe/ZMW0+4EBs/AphNTD1DA9FgCrL+bdJTxdtTJ0mYQDJT /2QNhbDqpRgYMYpx95rrDccVrUUzan22JVIYn4cpyPOkAnQ3goV5YmS4JrX+HIXzO1gp AQSeHpjzJ64+jRnusoibF28XnBiwhUtdnRVuKBh2iYX53cRQmrar7ISNRD4mgYiV2C3K hK2w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1732564767; x=1733169567; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=eWjtUwTz+qxGQM43m+Z3dIisqsvdUtxVeJqucaNK404=; b=c08CQ5uCold7R+7jzXvYlp2udEVUxnxhfCQ7E8PF/o68ft6vaeJSHmyGP3vz5Ifodb hnhhOAg+bG9bCB4oZ7ewZokVvJ8t7W9OrX4KGH4McPsjQkOa8dJwxh94Cwjy0pUUJvKn eBBQSNFxUYt0Dk7BY0IH/4+41HWJP31EjCIHu/jmONHTwJvbA62driS6M+Cl9H4poNEM T21MM6LmJjjYvutX18t/FN5T+oqe3gjV8XpTmDYbR/+gxdF7b8erZUcs/MSM+vgaedxm vx6FGxdCStyhFy/oy7WVrSdXiJJ31BpugOpB1M6S+g2Yz3/YpFdnBvsWediyBDY/FKUQ AFFQ== X-Forwarded-Encrypted: i=1; AJvYcCXnPM5Ef7KUtsHXYlGlhNXv5UrmojTi0HWB2ALGGr2BL51zf65ZzKmyc7q5oqkKu4XeBBCY3tWXDqKQ@nongnu.org X-Gm-Message-State: AOJu0YwkFdRwZErXJ9kNtbu4VbvYbXduur7qbmSmPm0D8knqMOYtZSil MYmkwoPMAogIhXv6bdAV7JURxsWanpZGYMy8trJBRqSBteuoeqihnYjQFvqWTmo= X-Gm-Gg: ASbGncufMcfjvQlR/yan1sgLrLhqOkdN6QUgufA+W6Dui5OSfJqqZF0QJ0w27Q9IpuY hlcMsG0vNagNvvEOuni5HDCAWVFlqp7ssyQEIeNV1vQMMb0tQ0crdOKrJwQFwJkgNpFuJ89yt07 7F6auRpvuw+M8izSNjUrspwxJk5gi2w501ZZ9yZWfWim6sm9DpTNfRRfxK8kO1ty/yHNVNV38U7 p9IX30NJN1qYhaYsWHDd6AS7owY8S9yWO4edwmHs4J17jYJ/kj3tytZOwwd7N/TMX23 X-Google-Smtp-Source: AGHT+IHn5QrVSKT8f+HZbb5tv4/jHNV6uqmDU1SLfzrB1hHig0KKaWqz8lFSXW23mKSBRR1e1l/D4Q== X-Received: by 2002:a05:600c:1c8f:b0:434:9e51:4db4 with SMTP id 5b1f17b1804b1-4349e515028mr48346395e9.6.1732564767551; Mon, 25 Nov 2024 11:59:27 -0800 (PST) Received: from localhost.localdomain ([2.221.137.100]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3825fd0fbdcsm11237971f8f.109.2024.11.25.11.59.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 25 Nov 2024 11:59:27 -0800 (PST) From: Jean-Philippe Brucker To: peter.maydell@linaro.org Cc: richard.henderson@linaro.org, philmd@linaro.org, qemu-arm@nongnu.org, qemu-devel@nongnu.org, alex.bennee@linaro.org, Jean-Philippe Brucker Subject: [PATCH v3 05/26] target/arm/kvm: Split kvm_arch_get/put_registers Date: Mon, 25 Nov 2024 19:56:04 +0000 Message-ID: <20241125195626.856992-7-jean-philippe@linaro.org> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241125195626.856992-2-jean-philippe@linaro.org> References: <20241125195626.856992-2-jean-philippe@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::32a; envelope-from=jean-philippe@linaro.org; helo=mail-wm1-x32a.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org The confidential guest support in KVM limits the number of registers that we can read and write. Split the get/put_registers function to prepare for it. Signed-off-by: Jean-Philippe Brucker --- target/arm/kvm.c | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/target/arm/kvm.c b/target/arm/kvm.c index 440c3ac8c6..0c80992f7c 100644 --- a/target/arm/kvm.c +++ b/target/arm/kvm.c @@ -2062,7 +2062,7 @@ static int kvm_arch_put_sve(CPUState *cs) return 0; } -int kvm_arch_put_registers(CPUState *cs, int level, Error **errp) +static int kvm_arm_put_core_regs(CPUState *cs, int level, Error **errp) { uint64_t val; uint32_t fpr; @@ -2165,6 +2165,19 @@ int kvm_arch_put_registers(CPUState *cs, int level, Error **errp) return ret; } + return 0; +} + +int kvm_arch_put_registers(CPUState *cs, int level, Error **errp) +{ + int ret; + ARMCPU *cpu = ARM_CPU(cs); + + ret = kvm_arm_put_core_regs(cs, level, errp); + if (ret) { + return ret; + } + write_cpustate_to_list(cpu, true); if (!write_list_to_kvmstate(cpu, level)) { @@ -2246,7 +2259,7 @@ static int kvm_arch_get_sve(CPUState *cs) return 0; } -int kvm_arch_get_registers(CPUState *cs, Error **errp) +static int kvm_arm_get_core_regs(CPUState *cs, Error **errp) { uint64_t val; unsigned int el; @@ -2349,6 +2362,19 @@ int kvm_arch_get_registers(CPUState *cs, Error **errp) } vfp_set_fpcr(env, fpr); + return 0; +} + +int kvm_arch_get_registers(CPUState *cs, Error **errp) +{ + int ret; + ARMCPU *cpu = ARM_CPU(cs); + + ret = kvm_arm_get_core_regs(cs, errp); + if (ret) { + return ret; + } + ret = kvm_get_vcpu_events(cpu); if (ret) { return ret; From patchwork Mon Nov 25 19:56:05 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Philippe Brucker X-Patchwork-Id: 13885227 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 15CA6D59D69 for ; Mon, 25 Nov 2024 20:03:42 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tFfFC-00054n-6a; Mon, 25 Nov 2024 14:59:38 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tFfFA-00053U-NP for qemu-devel@nongnu.org; Mon, 25 Nov 2024 14:59:36 -0500 Received: from mail-wm1-x32b.google.com ([2a00:1450:4864:20::32b]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1tFfF3-0004lm-Ik for qemu-devel@nongnu.org; Mon, 25 Nov 2024 14:59:36 -0500 Received: by mail-wm1-x32b.google.com with SMTP id 5b1f17b1804b1-4315c1c7392so44908285e9.1 for ; Mon, 25 Nov 2024 11:59:29 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1732564768; x=1733169568; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=tQShuah4RPH85LfDxttMiyLaDhN+5oe8+p7fsP3yrqw=; b=Hjp7ITOh5IP7JhGktCFoYf8vNtdYeQvOA2ogi7mXb/j0OvTQMWuYU4d1dfE70beTo8 43iLzcixST38wZV3y38WpWKvL2WeJ7CvqcbvgNL5mjz/MlgCOY+UafU3DIosbBC4otG7 HhSLs50Otuw+YDNhC2TjpaokCBkBcpQhLfduSDkY2QwFvnou/XVJNjDAAtnSnKH5dsKt u2ytpZUL90bzF5R6cF2AEfJFmBKM9acrnM63XKPJcDOUKKpDVzMkELxgUm3snijplE+r thdXhzwKRC3BI+JlItupjcaUS+iQzKd9/SWNYeQYG8LoX5nDUw/3tx/Xqb3WzGiVsDkL xU5A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1732564768; x=1733169568; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=tQShuah4RPH85LfDxttMiyLaDhN+5oe8+p7fsP3yrqw=; b=ki+tB4pcK2rDce2h1z1OjaKbR3sG1Nz2WXJ2Co/6x26NFDow0f36KYseoB0RSjTOZY sNpKPrHJDeHgFFQhncuGo/DjiuXnhjbLZIwP6pH1ctt1/9Hn9hUllRCRVS6ovOAuaB2L OhC7j0aA3fkVk7L1yUXxfuTFGrqdCMoHdaZvVQkFYL8NX0LBFCzd9rghnIqyhNxr4iBT Gy0z338iOANVM3JSDiQRToNtYe+dBgTuNjjs2rErXTJjfve5bxkUjKLUzgHc6wZ8wSYh ZMoJl29m5pyJ8drqGGiZ45HWvciJAvX84XNv+YHrxNyi7tsQG5bM9VWDlhcY7NKJLau7 cp4Q== X-Forwarded-Encrypted: i=1; AJvYcCXgTHmeE/O9M+PAlyvnuEXnYteOUOyupp6NSzBL6mRfIEFgcbVUmgUaST6iMgZzYgJo8Jtwp3EaB5JJ@nongnu.org X-Gm-Message-State: AOJu0Yx+KI6NmQHyOMkdF8a0NaSpqaAfAgceuDxeGOxxqpG/eTrld8Ei HDwelQ1fEjT09MCqbLaJSAxlyhIFZ78pDw2i1eiqgZlZzegYDKhGTJyb65drx7A= X-Gm-Gg: ASbGncu/g8WtU6uIDouTo5EWvpvykxVjL+bl0fdJi5sfEXStMyICFWpBLtzU74jAHHo 2nL4DbfR+Zl3f31kX519/oKuIGC+CePUFE2CKzDkVtKlkosofWHiljTs6DbYqDIdRvz6htPwvIY /IcpdQ01cMrZ/aq3O3gqqmHnwMh09ZQ6YUl3iMkepBh+J+F5HgohWcIdxMhk6hPRB2PM/Io/bfj pe1/Wmrpel/vkTPnPHxo5rh9B6sT53xsj8p5mZrk2yLeXvJwvFXfkLW53BUBnvUaafr X-Google-Smtp-Source: AGHT+IHu0epn53EoPbJ5rBYNXd0hSz17fN6MkrV+SiPxv6AdYWmai7LEbVLtwK/yGBV3nNkYp1vi2g== X-Received: by 2002:a05:6000:1f82:b0:37d:5364:d738 with SMTP id ffacd0b85a97d-38260bcc4cemr12792210f8f.45.1732564768083; Mon, 25 Nov 2024 11:59:28 -0800 (PST) Received: from localhost.localdomain ([2.221.137.100]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3825fd0fbdcsm11237971f8f.109.2024.11.25.11.59.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 25 Nov 2024 11:59:27 -0800 (PST) From: Jean-Philippe Brucker To: peter.maydell@linaro.org Cc: richard.henderson@linaro.org, philmd@linaro.org, qemu-arm@nongnu.org, qemu-devel@nongnu.org, alex.bennee@linaro.org, Jean-Philippe Brucker Subject: [PATCH v3 06/26] target/arm/kvm-rme: Initialize vCPU Date: Mon, 25 Nov 2024 19:56:05 +0000 Message-ID: <20241125195626.856992-8-jean-philippe@linaro.org> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241125195626.856992-2-jean-philippe@linaro.org> References: <20241125195626.856992-2-jean-philippe@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::32b; envelope-from=jean-philippe@linaro.org; helo=mail-wm1-x32b.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org The target code calls kvm_arm_vcpu_init() to mark the vCPU as part of a Realm. For a Realm vCPU, only x0-x7 can be set at runtime. Before boot, the PC can also be set, and is ignored at runtime. KVM also accepts a few system register changes during initial configuration, as returned by KVM_GET_REG_LIST. Signed-off-by: Jean-Philippe Brucker --- target/arm/cpu.h | 3 +++ target/arm/kvm_arm.h | 15 +++++++++++ target/arm/kvm-rme.c | 10 ++++++++ target/arm/kvm.c | 61 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 89 insertions(+) diff --git a/target/arm/cpu.h b/target/arm/cpu.h index d86e641280..f617591921 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -961,6 +961,9 @@ struct ArchCPU { OnOffAuto kvm_steal_time; #endif /* CONFIG_KVM */ + /* Realm Management Extension */ + bool kvm_rme; + /* Uniprocessor system with MP extensions */ bool mp_is_up; diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h index 9d6a89f9b1..8b52a881b0 100644 --- a/target/arm/kvm_arm.h +++ b/target/arm/kvm_arm.h @@ -245,6 +245,16 @@ int kvm_arm_rme_init(MachineState *ms); */ int kvm_arm_rme_vm_type(MachineState *ms); +/** + * kvm_arm_rme_vcpu_init + * @cs: the CPU + * + * If the user requested a Realm, setup the given vCPU accordingly. Realm vCPUs + * behave a little differently, for example most of their register state is + * hidden from the host. + */ +int kvm_arm_rme_vcpu_init(CPUState *cs); + #else /* @@ -339,6 +349,11 @@ static inline int kvm_arm_rme_vm_type(MachineState *ms) g_assert_not_reached(); } +static inline int kvm_arm_rme_vcpu_init(CPUState *cs) +{ + g_assert_not_reached(); +} + #endif #endif diff --git a/target/arm/kvm-rme.c b/target/arm/kvm-rme.c index 60d967a842..e3cc37538a 100644 --- a/target/arm/kvm-rme.c +++ b/target/arm/kvm-rme.c @@ -137,6 +137,16 @@ int kvm_arm_rme_init(MachineState *ms) return 0; } +int kvm_arm_rme_vcpu_init(CPUState *cs) +{ + ARMCPU *cpu = ARM_CPU(cs); + + if (rme_guest) { + cpu->kvm_rme = true; + } + return 0; +} + int kvm_arm_rme_vm_type(MachineState *ms) { if (rme_guest) { diff --git a/target/arm/kvm.c b/target/arm/kvm.c index 0c80992f7c..a0de2efc41 100644 --- a/target/arm/kvm.c +++ b/target/arm/kvm.c @@ -1926,6 +1926,11 @@ int kvm_arch_init_vcpu(CPUState *cs) return ret; } + ret = kvm_arm_rme_vcpu_init(cs); + if (ret) { + return ret; + } + if (cpu_isar_feature(aa64_sve, cpu)) { ret = kvm_arm_sve_set_vls(cpu); if (ret) { @@ -2062,6 +2067,35 @@ static int kvm_arch_put_sve(CPUState *cs) return 0; } +static int kvm_arm_rme_put_core_regs(CPUState *cs, Error **errp) +{ + int i, ret; + struct kvm_one_reg reg; + ARMCPU *cpu = ARM_CPU(cs); + CPUARMState *env = &cpu->env; + + /* + * The RME ABI only allows us to set 8 GPRs and the PC + */ + for (i = 0; i < 8; i++) { + reg.id = AARCH64_CORE_REG(regs.regs[i]); + reg.addr = (uintptr_t) &env->xregs[i]; + ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®); + if (ret) { + return ret; + } + } + + reg.id = AARCH64_CORE_REG(regs.pc); + reg.addr = (uintptr_t) &env->pc; + ret = kvm_vcpu_ioctl(cs, KVM_SET_ONE_REG, ®); + if (ret) { + return ret; + } + + return 0; +} + static int kvm_arm_put_core_regs(CPUState *cs, int level, Error **errp) { uint64_t val; @@ -2072,6 +2106,10 @@ static int kvm_arm_put_core_regs(CPUState *cs, int level, Error **errp) ARMCPU *cpu = ARM_CPU(cs); CPUARMState *env = &cpu->env; + if (cpu->kvm_rme) { + return kvm_arm_rme_put_core_regs(cs, errp); + } + /* If we are in AArch32 mode then we need to copy the AArch32 regs to the * AArch64 registers before pushing them out to 64-bit KVM. */ @@ -2259,6 +2297,25 @@ static int kvm_arch_get_sve(CPUState *cs) return 0; } +static int kvm_arm_rme_get_core_regs(CPUState *cs, Error **errp) +{ + int i, ret; + struct kvm_one_reg reg; + ARMCPU *cpu = ARM_CPU(cs); + CPUARMState *env = &cpu->env; + + for (i = 0; i < 8; i++) { + reg.id = AARCH64_CORE_REG(regs.regs[i]); + reg.addr = (uintptr_t) &env->xregs[i]; + ret = kvm_vcpu_ioctl(cs, KVM_GET_ONE_REG, ®); + if (ret) { + return ret; + } + } + + return 0; +} + static int kvm_arm_get_core_regs(CPUState *cs, Error **errp) { uint64_t val; @@ -2269,6 +2326,10 @@ static int kvm_arm_get_core_regs(CPUState *cs, Error **errp) ARMCPU *cpu = ARM_CPU(cs); CPUARMState *env = &cpu->env; + if (cpu->kvm_rme) { + return kvm_arm_rme_get_core_regs(cs, errp); + } + for (i = 0; i < 31; i++) { ret = kvm_get_one_reg(cs, AARCH64_CORE_REG(regs.regs[i]), &env->xregs[i]); From patchwork Mon Nov 25 19:56:06 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Philippe Brucker X-Patchwork-Id: 13885219 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 16B17D59D67 for ; Mon, 25 Nov 2024 20:01:08 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tFfFD-00055x-4h; Mon, 25 Nov 2024 14:59:39 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tFfFA-000530-1T for qemu-devel@nongnu.org; Mon, 25 Nov 2024 14:59:36 -0500 Received: from mail-wr1-x430.google.com ([2a00:1450:4864:20::430]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1tFfF4-0004m3-2H for qemu-devel@nongnu.org; Mon, 25 Nov 2024 14:59:35 -0500 Received: by mail-wr1-x430.google.com with SMTP id ffacd0b85a97d-382411ea5eeso2754575f8f.0 for ; Mon, 25 Nov 2024 11:59:29 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1732564768; x=1733169568; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=l6ECEauevFEDuaDl5024iGUaHxmj6lx8VtL68hjVAuI=; b=iuLxBJMGVBoxPF1UJDbA2Vv1OBWYbTtYScfkXCV61/kiTyEQAXG+SZfOPyBxJ0dHhP SPG5Mft6seqGOH4r3oPqIM00JwRAvMI29cbNnu1YpXzeMfssxWxo3wl5N8npQEMJtE9N Lm7KoK8eJn9xjEZ1krDjp89YU4EzGE9Zax4jSXZrNH6IBWgVgrN/OLfops3AxTLXqWmP PThUevk7U+onNLC0GKMePt92PK+BNNr4yuiwDyUPT951UHuAPfPP08wLBOzIUHRmjtcn xnTqeI+W6Ovn5ZgpDryC9n2BsR/rsbdNpnh86NPTuv6ZrO6i91xEEpBTT7MU2QyoyBBQ Jg8g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1732564768; x=1733169568; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=l6ECEauevFEDuaDl5024iGUaHxmj6lx8VtL68hjVAuI=; b=B2n/b3yVWaHhR/PWi2JEM/vKxSLuo6qnbg09zAo5GeeiGboKG4PY0Xrt07yQGPX8QE CP63gKl267E7659ovEa3HBdMNB2Ql2r+VfvJpRZbUQw5un6ELBQ4KFDUuUqs/6McaJzX 7sWJgDkElDfdwlUQ851lGXjRtSm/0dGzCT1Cqk8O0NMyZP+EjktoPa+s+2sjPhRtOs7f gL+GeqwWOSFswrq+k0ajcOAtWhmgu/Eoyo0ZaW3OcxrGayENv36KmNF8Hsua01m4k4NY PAUOvNQxOZ1I4wMagre6Heu3cV1CWrZHsebXbMMSr+ZOwNcXpppHXecAebUE+1yP1cfW HSwQ== X-Forwarded-Encrypted: i=1; AJvYcCVrt/2VTRYLDn1Hv0BEWv118BH9QrbYV+ErTitKWxh9pS0/F4K/s+pLmElz1xz0HO5WGgB5YLbIo1Ih@nongnu.org X-Gm-Message-State: AOJu0YwjY1+1Cc4owolfyTJy5CINn5oJowimNEha5j1bUT0q36M/Nbq+ x4FmvYEdyHBR0jxuA/G8sg23E5JKtJ5vSe3eUn5hCLcsMp4vri61SKsWPFJ7nkE= X-Gm-Gg: ASbGnctV3tjwo2G5gD1WKMs4OWVEKEHfSHWNbN12/8/78ha9qwxuKYvEk9Lpg/Olauk ox+ZthZrDYlJEr63vKuTpNwlfTrOrCqlbU0/o0Q5ex0GLyzO45XqF/LuzDGsP32S4fj0p2IrvHg ag9WC7B19R3xTO5OAywbP5WRQFOK9grsnRadobgyEDaIV6doBi1T5C/mwwqUvniYyi9AHpGZCXi /h9oD268lhOsPyJ0S1HYzIOEcF2Q/lL60GeA8thiTlJvvlBB07HWONJt5mhZO9ugPbE X-Google-Smtp-Source: AGHT+IGbZl3AY2mB9oOWxAvM4IlArET44A1YQ5dGHlD5vZZFWUk/pyqrC23UoIgvZPpYjMWvWh/3Pg== X-Received: by 2002:a5d:6d84:0:b0:37d:3780:31d2 with SMTP id ffacd0b85a97d-385bfaf0c1bmr602579f8f.15.1732564768631; Mon, 25 Nov 2024 11:59:28 -0800 (PST) Received: from localhost.localdomain ([2.221.137.100]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3825fd0fbdcsm11237971f8f.109.2024.11.25.11.59.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 25 Nov 2024 11:59:28 -0800 (PST) From: Jean-Philippe Brucker To: peter.maydell@linaro.org Cc: richard.henderson@linaro.org, philmd@linaro.org, qemu-arm@nongnu.org, qemu-devel@nongnu.org, alex.bennee@linaro.org, Jean-Philippe Brucker Subject: [PATCH v3 07/26] target/arm/kvm: Create scratch VM as Realm if necessary Date: Mon, 25 Nov 2024 19:56:06 +0000 Message-ID: <20241125195626.856992-9-jean-philippe@linaro.org> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241125195626.856992-2-jean-philippe@linaro.org> References: <20241125195626.856992-2-jean-philippe@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::430; envelope-from=jean-philippe@linaro.org; helo=mail-wr1-x430.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Some ID registers have a different value for a Realm VM, for example ID_AA64DFR0_EL1 contains the number of breakpoints/watchpoints implemented by RMM instead of the hardware. Even though RMM is in charge of setting up most Realm registers, KVM still provides GET_ONE_REG interface on a Realm VM to probe the VM's capabilities. Signed-off-by: Jean-Philippe Brucker --- target/arm/kvm.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/target/arm/kvm.c b/target/arm/kvm.c index a0de2efc41..870f51bf02 100644 --- a/target/arm/kvm.c +++ b/target/arm/kvm.c @@ -106,6 +106,7 @@ bool kvm_arm_create_scratch_host_vcpu(const uint32_t *cpus_to_try, { int ret = 0, kvmfd = -1, vmfd = -1, cpufd = -1; int max_vm_pa_size; + int vm_type; kvmfd = qemu_open_old("/dev/kvm", O_RDWR); if (kvmfd < 0) { @@ -115,8 +116,9 @@ bool kvm_arm_create_scratch_host_vcpu(const uint32_t *cpus_to_try, if (max_vm_pa_size < 0) { max_vm_pa_size = 0; } + vm_type = kvm_arm_rme_vm_type(MACHINE(qdev_get_machine())); do { - vmfd = ioctl(kvmfd, KVM_CREATE_VM, max_vm_pa_size); + vmfd = ioctl(kvmfd, KVM_CREATE_VM, max_vm_pa_size | vm_type); } while (vmfd == -1 && errno == EINTR); if (vmfd < 0) { goto err; From patchwork Mon Nov 25 19:56:07 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Philippe Brucker X-Patchwork-Id: 13885241 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 563CED59D6A for ; Mon, 25 Nov 2024 20:06:08 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tFfFL-0005FZ-EL; Mon, 25 Nov 2024 14:59:47 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tFfFB-00054b-PC for qemu-devel@nongnu.org; Mon, 25 Nov 2024 14:59:37 -0500 Received: from mail-wr1-x432.google.com ([2a00:1450:4864:20::432]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1tFfF4-0004mQ-Lr for qemu-devel@nongnu.org; Mon, 25 Nov 2024 14:59:37 -0500 Received: by mail-wr1-x432.google.com with SMTP id ffacd0b85a97d-382325b0508so3216491f8f.3 for ; Mon, 25 Nov 2024 11:59:30 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1732564769; x=1733169569; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=JcJPrbjMCLmh0eNMSHwL1G2MB7wFRr0T2Y0cUgmEayE=; b=eMo1bxiMPDGqZSG/Uw39HPRSZ7h8wREm/Jgxf1+iA6btKsaE/DknIuKkuE/wM8DZDf vZfuwpm8UrgemmaDDl3C05i/gV5yO62hjK/vYVLzcuXP3vV1PDkcJHz7+yK5CAHd3VCl eXh7NAtrYx28y7+FlGvINpn+FZcQd6vzfCeTviWzG3Q2Ox1Ttr4I91CPqviKkutVZaE1 omod1SMRGE85FzDdO6dyavzEZcrD24b9TPTHfzM+QvoLy4YnssiWgHg7SgmRv5r3SMIO nwex9ZlLeK1/alCQ7ZvA89JrI3Y3esd+6OqPdtAHNzg8Dm+DtYmC2nD/RQu0F20TxViE fu5g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1732564769; x=1733169569; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=JcJPrbjMCLmh0eNMSHwL1G2MB7wFRr0T2Y0cUgmEayE=; b=e+B14OJ/izMgxvZNgwRaSk2c9iETbkkadrJ/0R/B1tYGD//sFDjgp7sxpAtUk78a4X 4y/Ia7fXCnsHTdXo20xIsCnM2VMsNj7rLETs1+Mt727CjocZ+IkWZVbk/xUd/9ShH1SI LuEL6vwmBXD5SIqPFPXkcB8xjOBvHjN/lb89nHigDLlkHXKO/6y2BELSbjkETLJIcFJ5 sC+m8t2Onb3uRId2Kx7m//YvWS037lYS8bMorGSKAelzVDOjFExqkJ4OZb4thDQHDBNe qZkR7jvA4gtdEZNLtS6O7NJ0xOJM9cLF9pZ6+UiuTTtZr38ixlFbbTwGtBNTkEchRtz4 134Q== X-Forwarded-Encrypted: i=1; AJvYcCX8Yg6/6EfUhP+I/h4fW1k7q5P9Dl/nPHEA91yRS+U5sLNMjPet/8nDz/HpjdHtVqabms4sSmoiMy2t@nongnu.org X-Gm-Message-State: AOJu0Yw1mpGR/kW+i6KC/YZEm7qR5RvRZcFZMhZTsbEmey6jYSc6N/0J rrQoIcu7U0NA5JecnqfxFtzcHSUNanmy125cOpEim1KLlBZYcfjcoKNSX2Zupnw= X-Gm-Gg: ASbGncuTpAGQUCGBocMJ69SGzTZfhUZJ8ek9L22vBkGUD5mHAWRQ+R3cw8DRZSOlWX8 VlBkSl7QAaAeut+tjWNVOkppbbVQr5onB+lYdrL978lwVcVI1nno3o8pOGdHRZ4pBAbS1nqLA0q 3/VHT961+8U9m5i+D7gDqqHnFZKBACg3b9OC04x7aAG/aXleiv8C6C/yv0JgFI250ualqvw4UID iGI8EmehKTvdPzdcWZIrvAxHijN27sGEsIbTx5b9hJxLYKSiSA7+IwBASqOLuAOyMmi X-Google-Smtp-Source: AGHT+IEg6YuxoILvMPLYuVly61vnvw6FfSnv0Ejz5HnIAwlyt73nF1r2uz5gua2PinPmEU6MzS2shQ== X-Received: by 2002:a05:6000:1fab:b0:382:4aa0:e728 with SMTP id ffacd0b85a97d-38260b46dd6mr12738762f8f.1.1732564769159; Mon, 25 Nov 2024 11:59:29 -0800 (PST) Received: from localhost.localdomain ([2.221.137.100]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3825fd0fbdcsm11237971f8f.109.2024.11.25.11.59.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 25 Nov 2024 11:59:28 -0800 (PST) From: Jean-Philippe Brucker To: peter.maydell@linaro.org Cc: richard.henderson@linaro.org, philmd@linaro.org, qemu-arm@nongnu.org, qemu-devel@nongnu.org, alex.bennee@linaro.org, Jean-Philippe Brucker Subject: [PATCH v3 08/26] hw/core/loader: Add ROM loader notifier Date: Mon, 25 Nov 2024 19:56:07 +0000 Message-ID: <20241125195626.856992-10-jean-philippe@linaro.org> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241125195626.856992-2-jean-philippe@linaro.org> References: <20241125195626.856992-2-jean-philippe@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::432; envelope-from=jean-philippe@linaro.org; helo=mail-wr1-x432.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Add a function to register a notifier, that is invoked after a ROM gets loaded into guest memory. It will be used by Arm confidential guest support, in order to register all blobs loaded into memory with KVM, so that their content is moved into Realm state and measured into the initial VM state. Signed-off-by: Jean-Philippe Brucker --- include/hw/loader.h | 15 +++++++++++++++ hw/core/loader.c | 15 +++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/include/hw/loader.h b/include/hw/loader.h index 7f6d06b956..0cd9905f97 100644 --- a/include/hw/loader.h +++ b/include/hw/loader.h @@ -353,6 +353,21 @@ void *rom_ptr_for_as(AddressSpace *as, hwaddr addr, size_t size); ssize_t rom_add_vga(const char *file); ssize_t rom_add_option(const char *file, int32_t bootindex); +typedef struct RomLoaderNotify { + /* Parameters passed to rom_add_blob() */ + hwaddr addr; + size_t len; + size_t max_len; +} RomLoaderNotify; + +/** + * rom_add_load_notifier - Add a notifier for loaded images + * + * Add a notifier that will be invoked with a RomLoaderNotify structure for each + * blob loaded into guest memory, after the blob is loaded. + */ +void rom_add_load_notifier(Notifier *notifier); + /* This is the usual maximum in uboot, so if a uImage overflows this, it would * overflow on real hardware too. */ #define UBOOT_MAX_GUNZIP_BYTES (64 << 20) diff --git a/hw/core/loader.c b/hw/core/loader.c index 31593a1171..759a62cf58 100644 --- a/hw/core/loader.c +++ b/hw/core/loader.c @@ -67,6 +67,8 @@ #include static int roms_loaded; +static NotifierList rom_loader_notifier = + NOTIFIER_LIST_INITIALIZER(rom_loader_notifier); /* return the size or -1 if error */ int64_t get_image_size(const char *filename) @@ -1179,6 +1181,11 @@ MemoryRegion *rom_add_blob(const char *name, const void *blob, size_t len, return mr; } +void rom_add_load_notifier(Notifier *notifier) +{ + notifier_list_add(&rom_loader_notifier, notifier); +} + /* This function is specific for elf program because we don't need to allocate * all the rom. We just allocate the first part and the rest is just zeros. This * is why romsize and datasize are different. Also, this function takes its own @@ -1220,6 +1227,7 @@ ssize_t rom_add_option(const char *file, int32_t bootindex) static void rom_reset(void *unused) { Rom *rom; + RomLoaderNotify notify; QTAILQ_FOREACH(rom, &roms, next) { if (rom->fw_file) { @@ -1268,6 +1276,13 @@ static void rom_reset(void *unused) cpu_flush_icache_range(rom->addr, rom->datasize); trace_loader_write_rom(rom->name, rom->addr, rom->datasize, rom->isrom); + + notify = (RomLoaderNotify) { + .addr = rom->addr, + .len = rom->datasize, + .max_len = rom->romsize, + }; + notifier_list_notify(&rom_loader_notifier, ¬ify); } } From patchwork Mon Nov 25 19:56:08 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Philippe Brucker X-Patchwork-Id: 13885222 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id D9665D59D67 for ; Mon, 25 Nov 2024 20:01:52 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tFfFF-00058a-Rt; Mon, 25 Nov 2024 14:59:42 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tFfFD-00056J-9E for qemu-devel@nongnu.org; Mon, 25 Nov 2024 14:59:39 -0500 Received: from mail-wm1-x332.google.com ([2a00:1450:4864:20::332]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1tFfF5-0004mk-QY for qemu-devel@nongnu.org; Mon, 25 Nov 2024 14:59:38 -0500 Received: by mail-wm1-x332.google.com with SMTP id 5b1f17b1804b1-4315e9e9642so44610845e9.0 for ; Mon, 25 Nov 2024 11:59:31 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1732564770; x=1733169570; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Oo1EgfoyArPx0QyjZUVlmbBpOKVgCXNN/Sfqm4FiXXo=; b=mieKa2DMzTeXllctCe6oPxhkEn80nnS3hJD8WSMTy29YMtHD8JJ9dwAZdmymZssaM+ qkD5e/r24gdy4F/pZEeQToorGM1tXXKeQBtoPIOuFkAk6vo3Oigz2V5OyPqMJI/zhS7C 1ytrUYN9R6rzTcpG8oYBCr51/siNIfwAE9rp4jz+bkv7wbVnz2wuGApOeI5NCFYDdHp8 XNFdBybGT++Xld6qiwuqXpvADCsNRzWoDK+c2tKqBUlBToSSM65oAvQiOKpe90wbGG3Q UuIblbqYoYrAO1K+k/b7SusKUpP+HmOFRxjIM9NaRuiCWklGP+1g2IU+FBZAeX+59ibd bKBA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1732564770; x=1733169570; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Oo1EgfoyArPx0QyjZUVlmbBpOKVgCXNN/Sfqm4FiXXo=; b=MVT2DtS3qhxYrWpMcGzFRjJyUX8DxLkdDj+++XubxC0yzWN5/yIuSQ/w9GiWz/Ngb9 1B7y/L1h9lSyUcyflVK1eBG5DKaUlL0HyuiAPnW31lKsY9ICCWBSSl3QHA+YHi0QCI6R QtqCLWFZf+eSeG6ao+frTLVxWaTrwJOtQIK6qdKk3i7cPgfJrPgZOBo+dfJj000x9qEa uAnHFp8SJnC7q/98JvqNkchehvB37w6ONeoTaadpoXGpJJI2l/FMiWwAJR8REgWBWfDZ KGSgm2DMn21bQgVkcIIvryaBXr+xyAZXFpWEeG/y4kiT934gaC5b7mE2cpsVpBMb1YmO lOsw== X-Forwarded-Encrypted: i=1; AJvYcCX3SWlpb1eHC+sKQF+2Ef3ZDJ7FDELZLdHYWWhIsjP2sNo4kbxlmsqUmvnxvyauHsy7qDbxERLoVhge@nongnu.org X-Gm-Message-State: AOJu0YzrnqiA1iZj2/ZFaJ56tmgxnIRjfu6GhpNLarnhCWVXiUW6uk2a P6PSL/QW/45fk9KQpbUf7/v3q5u1lOhgtv5xE9x90SHfAqtFkPq70ahxPCxH1S8THNuFUhH84ly I X-Gm-Gg: ASbGncswGzWPRTBE3cgHo6u+sa8N4OUDRZptP6186r6b5V3lT8oc1zZsdCqaG7AWz6p NlMdyIdglcsffVdLpMAX4PFq0D/Cz0+W/iOcy9mQkSiJDJ0orog2XwEXeObY5peq41VyNYaOYS3 S/wChpakyfl50FwyxnKOjDhwlSXo1giLv2E3EC8Bsu6XdSNHlO5sv+OvgLWbtKfA9UQNCXoFzQm +ipag/llkab38nDAkNxQ1ELYwldaudL1VhMMqHg2pP5PDzZ0oGOlOV/ekcwDts3Mh66 X-Google-Smtp-Source: AGHT+IGEuG55nfDajrGEaz7M/kGNc1ktpiuJCiuV/narivEo/mrkiiTEuTAGFHtr+tUvMIFwJ0tt4A== X-Received: by 2002:a05:600c:1f85:b0:431:5ce4:bcf0 with SMTP id 5b1f17b1804b1-433ce428100mr134775805e9.15.1732564769711; Mon, 25 Nov 2024 11:59:29 -0800 (PST) Received: from localhost.localdomain ([2.221.137.100]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3825fd0fbdcsm11237971f8f.109.2024.11.25.11.59.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 25 Nov 2024 11:59:29 -0800 (PST) From: Jean-Philippe Brucker To: peter.maydell@linaro.org Cc: richard.henderson@linaro.org, philmd@linaro.org, qemu-arm@nongnu.org, qemu-devel@nongnu.org, alex.bennee@linaro.org, Jean-Philippe Brucker Subject: [PATCH v3 09/26] target/arm/kvm-rme: Initialize Realm memory Date: Mon, 25 Nov 2024 19:56:08 +0000 Message-ID: <20241125195626.856992-11-jean-philippe@linaro.org> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241125195626.856992-2-jean-philippe@linaro.org> References: <20241125195626.856992-2-jean-philippe@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::332; envelope-from=jean-philippe@linaro.org; helo=mail-wm1-x332.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org 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 --- 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; }; 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")", + 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); From patchwork Mon Nov 25 19:56:09 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jean-Philippe Brucker X-Patchwork-Id: 13885242 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id EACD9D59D67 for ; Mon, 25 Nov 2024 20:06:39 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tFfFH-00059g-1Y; Mon, 25 Nov 2024 14:59:43 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tFfFC-00054e-2M for qemu-devel@nongnu.org; Mon, 25 Nov 2024 14:59:38 -0500 Received: from mail-wm1-x32c.google.com ([2a00:1450:4864:20::32c]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1tFfF5-0004mi-Qh for qemu-devel@nongnu.org; Mon, 25 Nov 2024 14:59:37 -0500 Received: by mail-wm1-x32c.google.com with SMTP id 5b1f17b1804b1-4349e4e252dso14143405e9.0 for ; Mon, 25 Nov 2024 11:59:31 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1732564770; x=1733169570; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=0m2/9HP5vLC3hqAB+yCWUJo/ObLxgmWN4DQPmhXmpqg=; b=IO8bh0b1Lg3AXHFPiZ6/vhc8JpJxzwzcq69+YD7LgchLqCEIieqhRLehBuMaVcQsB4 nsaRitJjBLgw8oVq+B9W5AnGcBXzSJ2p1fKuI75sQ1+kAGOKhBpajXGgU4oEjjGqgkZG MfahVcLK3z79rfSKfIWk8TCkfDPyOaad9q8pUG+OnyMl+bGAe3TnuzsO7loVvOt7ztT9 +4bveJ3pUDML1KiUS9PZfHA4qLjjxfJZIac9WtSel2VDo7DWxBzrj/U9yaPBMqLvanQE vgca284IxUu44O788y8jwEYd9MfXG5nhG0Z+mHBvyYw3xpmm34dSx6ne+m/A/R/2rhmL pzFQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1732564770; x=1733169570; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=0m2/9HP5vLC3hqAB+yCWUJo/ObLxgmWN4DQPmhXmpqg=; b=I8BxnwzycCPrdj4X0sNVmFSHr6dWxsM5WgZTikzfVmx4uzXmxsMHUcoKdoQC86yQB+ HBNdnoXjxaRA8aNy0dWLBacCSv51BKwSg4lZuwJv27KmNbcmE9j3++/R0Ct6fhho67UE mClAMlPI6RU7snAobsdZRnInE/+VIe3dfsRRPwqtnsJCT1Abg1wyuJQHfRxF9hsC10Gt zmXZcDJuuF8+GLtds3pjzVIydxf+/X/wvHNbrNmM0mavd8kC9KxOEe7lQ+sUipVeLlcf fESTwx9Ap6IJtwYV5suta09xdk1ghwpBL8xvHEDzlFKozdmQFCI9ZyNeN2/ZaqykgokO R/5g== X-Forwarded-Encrypted: i=1; AJvYcCXWbYW9r7dep4+4yKlhJhI4sPVOI4CIl23aNNJGxOirQcol2qL3ETZIIFVGbTBc/0OG7GNUJDKRWyyF@nongnu.org X-Gm-Message-State: AOJu0YzWTIemlvN/zW6M9Kqlv4Ja6T4tAeHk/m7TRsTfGJuT8nYOC8Fa ol7ioXWt3O+ICBP5gaavtLd0WyN/E2ACuSrFp7QK7kcQwxpjafkQtJfkONf1cLw= X-Gm-Gg: ASbGnctEikYbZSMMVeSycRtKD2/Z0mgsHGzHDNOF9BFOtpQlT9TiND1kWuF5fAoVOEU 0rtzBZhfHtzFiPVTQOIBPPS9eGSWq3PuwTSI6i6dT60pSoiPaxLQz6CoMmZfYg9R9ZZk0QKKFLS sinO8heOTXdIYlWHETr4hivJOMI+ODRgZUHKAi4Q4/Li8nO+osSvr9AEMvXNEbxVen+lq5D72T7 vyCCWnHe6GMXXygWjEEfy41txLZOw1D8Ji4kFjaYYFxFpgt5aaZtgUAE0cINzqe4cNL X-Google-Smtp-Source: AGHT+IHIgHFWvVyyJCi5WA7qSU1TvSslIX+EBQ+ux7JHA9WcmEKKX7xGvPmRb34R9SzN6GO/cTMdzA== X-Received: by 2002:a05:6000:2d08:b0:382:50d9:bc7c with SMTP id ffacd0b85a97d-38260be6bfamr7331722f8f.58.1732564770312; Mon, 25 Nov 2024 11:59:30 -0800 (PST) Received: from localhost.localdomain ([2.221.137.100]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3825fd0fbdcsm11237971f8f.109.2024.11.25.11.59.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 25 Nov 2024 11:59:30 -0800 (PST) From: Jean-Philippe Brucker To: peter.maydell@linaro.org Cc: richard.henderson@linaro.org, philmd@linaro.org, qemu-arm@nongnu.org, qemu-devel@nongnu.org, alex.bennee@linaro.org, Jean-Philippe Brucker , Eric Blake , Markus Armbruster , =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= , Eduardo Habkost Subject: [PATCH v3 10/26] target/arm/kvm-rme: Add Realm Personalization Value parameter Date: Mon, 25 Nov 2024 19:56:09 +0000 Message-ID: <20241125195626.856992-12-jean-philippe@linaro.org> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241125195626.856992-2-jean-philippe@linaro.org> References: <20241125195626.856992-2-jean-philippe@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::32c; envelope-from=jean-philippe@linaro.org; helo=mail-wm1-x32c.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org The Realm Personalization Value (RPV) is provided by the user to distinguish Realms that have the same initial measurement. The user provides up to 64 hexadecimal bytes. They are stored into the RPV in the same order, zero-padded on the right. Cc: Eric Blake Cc: Markus Armbruster Cc: Daniel P. Berrangé Cc: Eduardo Habkost Acked-by: Markus Armbruster Signed-off-by: Jean-Philippe Brucker --- v2->v3: Fix documentation --- qapi/qom.json | 15 ++++++ target/arm/kvm-rme.c | 111 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 126 insertions(+) diff --git a/qapi/qom.json b/qapi/qom.json index a8beeabf1f..f982850bca 100644 --- a/qapi/qom.json +++ b/qapi/qom.json @@ -1068,6 +1068,19 @@ 'data': { '*cpu-affinity': ['uint16'], '*node-affinity': ['uint16'] } } +## +# @RmeGuestProperties: +# +# Properties for rme-guest objects. +# +# @personalization-value: Realm personalization value, as a 64-byte +# hex string. This optional parameter allows to uniquely identify +# the VM instance during attestation. (default: 0) +# +# Since: 9.3 +## +{ 'struct': 'RmeGuestProperties', + 'data': { '*personalization-value': 'str' } } ## # @ObjectType: @@ -1121,6 +1134,7 @@ { 'name': 'pr-manager-helper', 'if': 'CONFIG_LINUX' }, 'qtest', + 'rme-guest', 'rng-builtin', 'rng-egd', { 'name': 'rng-random', @@ -1195,6 +1209,7 @@ 'pr-manager-helper': { 'type': 'PrManagerHelperProperties', 'if': 'CONFIG_LINUX' }, 'qtest': 'QtestProperties', + 'rme-guest': 'RmeGuestProperties', 'rng-builtin': 'RngProperties', 'rng-egd': 'RngEgdProperties', 'rng-random': { 'type': 'RngRandomProperties', diff --git a/target/arm/kvm-rme.c b/target/arm/kvm-rme.c index 83a29421df..0be55867ee 100644 --- a/target/arm/kvm-rme.c +++ b/target/arm/kvm-rme.c @@ -23,11 +23,15 @@ OBJECT_DECLARE_SIMPLE_TYPE(RmeGuest, RME_GUEST) #define RME_PAGE_SIZE qemu_real_host_page_size() +#define RME_MAX_CFG 1 + struct RmeGuest { ConfidentialGuestSupport parent_obj; Notifier rom_load_notifier; GSList *ram_regions; + uint8_t *personalization_value; + hwaddr ram_base; size_t ram_size; }; @@ -43,6 +47,48 @@ typedef struct { static RmeGuest *rme_guest; +static int rme_configure_one(RmeGuest *guest, uint32_t cfg, Error **errp) +{ + int ret; + const char *cfg_str; + struct kvm_cap_arm_rme_config_item args = { + .cfg = cfg, + }; + + switch (cfg) { + case KVM_CAP_ARM_RME_CFG_RPV: + if (!guest->personalization_value) { + return 0; + } + memcpy(args.rpv, guest->personalization_value, KVM_CAP_ARM_RME_RPV_SIZE); + cfg_str = "personalization value"; + break; + default: + g_assert_not_reached(); + } + + ret = kvm_vm_enable_cap(kvm_state, KVM_CAP_ARM_RME, 0, + KVM_CAP_ARM_RME_CONFIG_REALM, (intptr_t)&args); + if (ret) { + error_setg_errno(errp, -ret, "failed to configure %s", cfg_str); + } + return ret; +} + +static int rme_configure(Error **errp) +{ + int ret; + int cfg; + + for (cfg = 0; cfg < RME_MAX_CFG; cfg++) { + ret = rme_configure_one(rme_guest, cfg, errp); + if (ret) { + return ret; + } + } + return 0; +} + static int rme_init_ram(hwaddr base, size_t size, Error **errp) { int ret; @@ -123,6 +169,10 @@ static int rme_create_realm(Error **errp) { int ret; + if (rme_configure(errp)) { + return -1; + } + ret = kvm_vm_enable_cap(kvm_state, KVM_CAP_ARM_RME, 0, KVM_CAP_ARM_RME_CREATE_RD); if (ret) { @@ -168,8 +218,69 @@ static void rme_vm_state_change(void *opaque, bool running, RunState state) } } +static char *rme_get_rpv(Object *obj, Error **errp) +{ + RmeGuest *guest = RME_GUEST(obj); + GString *s; + int i; + + if (!guest->personalization_value) { + return NULL; + } + + s = g_string_sized_new(KVM_CAP_ARM_RME_RPV_SIZE * 2 + 1); + + for (i = 0; i < KVM_CAP_ARM_RME_RPV_SIZE; i++) { + g_string_append_printf(s, "%02x", guest->personalization_value[i]); + } + + return g_string_free(s, /* free_segment */ false); +} + +static void rme_set_rpv(Object *obj, const char *value, Error **errp) +{ + RmeGuest *guest = RME_GUEST(obj); + size_t len = strlen(value); + uint8_t *out; + int i = 1; + int ret; + + g_free(guest->personalization_value); + guest->personalization_value = out = g_malloc0(KVM_CAP_ARM_RME_RPV_SIZE); + + /* Two chars per byte */ + if (len > KVM_CAP_ARM_RME_RPV_SIZE * 2) { + error_setg(errp, "Realm Personalization Value is too large"); + return; + } + + /* First byte may have a single char */ + if (len % 2) { + ret = sscanf(value, "%1hhx", out++); + } else { + ret = sscanf(value, "%2hhx", out++); + i++; + } + if (ret != 1) { + error_setg(errp, "Invalid Realm Personalization Value"); + return; + } + + for (; i < len; i += 2) { + ret = sscanf(value + i, "%2hhx", out++); + if (ret != 1) { + error_setg(errp, "Invalid Realm Personalization Value"); + return; + } + } +} + static void rme_guest_class_init(ObjectClass *oc, void *data) { + object_class_property_add_str(oc, "personalization-value", rme_get_rpv, + rme_set_rpv); + object_class_property_set_description(oc, "personalization-value", + "Realm personalization value (512-bit hexadecimal number)"); } static void rme_guest_init(Object *obj) From patchwork Mon Nov 25 19:56:10 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jean-Philippe Brucker X-Patchwork-Id: 13885216 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 7302DD59D67 for ; Mon, 25 Nov 2024 19:59:55 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tFfFG-00058i-HM; Mon, 25 Nov 2024 14:59:42 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tFfFD-00056L-CK for qemu-devel@nongnu.org; Mon, 25 Nov 2024 14:59:39 -0500 Received: from mail-wm1-x334.google.com ([2a00:1450:4864:20::334]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1tFfF6-0004nV-Di for qemu-devel@nongnu.org; Mon, 25 Nov 2024 14:59:39 -0500 Received: by mail-wm1-x334.google.com with SMTP id 5b1f17b1804b1-434a2033562so6798755e9.1 for ; Mon, 25 Nov 2024 11:59:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1732564771; x=1733169571; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=DFJSI53cHJ1N3Z+oLQAsbnNAF3KjE8o1K+yxUpabOQA=; b=EJy89L2tzAcoZnpAoYqpUW1MJEREfmJaTYG7P6j+GshhBsDZ9tnIPEqa1glCO0SzOc QtyEw/vcch53UsKDT4UBuB6zzEsji4ULKS2yjRUYa80aNcV7BScHvi57qd8v+198UTBQ Q9M67xAkUXehAcxIIZ2ZXuEolZTurw0kW4HMGsY0AO2EcbZbe9+qaYhrCFbsP9SMzu32 VdkBn/Nu7FmDV35eiotqNCZZUhLAIttrSJrXMyaIkdKvc3UirQN+L25LDdUhvdhqo42V hwOm0yC7FHHKc4eUUFnJGZcuihbPhLyubmfmAarZLmfYbIhnuLsipxgTI3s6YFuBhfFT 3BgA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1732564771; x=1733169571; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=DFJSI53cHJ1N3Z+oLQAsbnNAF3KjE8o1K+yxUpabOQA=; b=RKrC+TqUllAw4n//KCkqNxMB1I0LxPOat6BOJ572phfoXSKtXdnBaDzFE4r/TYmAAE Ht9J7VILa4kuVpSNZYgTBdFP4da6fgmGMplTTkynfRZDCNHk2TByW+aOoBuvF/9vWKpv 1TRxJ5qd/wFCBN+5H/NxMbyWc11E9H/knJh2dYZzBuoD0VlsYdChpv77FwVTNl0SH3Bz BvOFFIpYQtBlAjeD4SM6HFLg/VAh54AdRyELX2NXVE/6XzGsBuIFwPL1jTkmew3ImWaD zUnnqMu0B2fOt/QFIeCc8zmH92aeXAEyj/N5SrHLngtSZJQLAlby6zyjU39sIt2aT043 XKhw== X-Forwarded-Encrypted: i=1; AJvYcCWixMgVltqW1rJ7Qg0QvUC4IXDlCdJNTMVvhOHhF4cshKc//dCCBrB/5Qd2bw7BEE/ZGx9tW8BpjSkB@nongnu.org X-Gm-Message-State: AOJu0YzQK9Hd/AMQZyxgTXO+pQnUP4mQdPtU44CsQmDhJxSpQz0REVuI cW2jJBPHtFR63ZS8nUMPXqLIsKRyB4izNkCeQiffC46kvBmEzuGhDuCvo829B/VNZ/5Jf+Py+yx H X-Gm-Gg: ASbGncuN0zQXFOq01aYzzohXeso3swhKgKyN6EOoplSiW9efAkEaRFrJyNR/XhJSi3V RHqCGpVPsGdCb+I5psu/6coq6aIs3YdWpVMfjJXzStI5bZk4aHxKXK5urDDspzcwOTmtU5dyWX/ X7IcvXJoNvCWWQOj9xbInAWh0mVVrDVeVrLcMu6SLI1dHgL5EV0siRQKpIUPAkpu6umCAo7TsM0 3TYY/tIj17POStMNqY5ZbefgBBDBpbpaKq8CoR5RymjACLMoQxWREdbpTR78wlGbl88 X-Google-Smtp-Source: AGHT+IFReC0jAoBg3T5lkRnllyjlOiG9tzJlifErfsEXB7qfxFxhKbbca1oQPz7uQOdlOYwByoQPlw== X-Received: by 2002:a05:600c:1990:b0:434:a555:d0d with SMTP id 5b1f17b1804b1-434a5551bbamr2381835e9.29.1732564770965; Mon, 25 Nov 2024 11:59:30 -0800 (PST) Received: from localhost.localdomain ([2.221.137.100]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3825fd0fbdcsm11237971f8f.109.2024.11.25.11.59.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 25 Nov 2024 11:59:30 -0800 (PST) From: Jean-Philippe Brucker To: peter.maydell@linaro.org Cc: richard.henderson@linaro.org, philmd@linaro.org, qemu-arm@nongnu.org, qemu-devel@nongnu.org, alex.bennee@linaro.org, Jean-Philippe Brucker , Eric Blake , Markus Armbruster , =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= , Eduardo Habkost Subject: [PATCH v3 11/26] target/arm/kvm-rme: Add measurement algorithm property Date: Mon, 25 Nov 2024 19:56:10 +0000 Message-ID: <20241125195626.856992-13-jean-philippe@linaro.org> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241125195626.856992-2-jean-philippe@linaro.org> References: <20241125195626.856992-2-jean-philippe@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::334; envelope-from=jean-philippe@linaro.org; helo=mail-wm1-x334.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org This option selects which measurement algorithm to use for attestation. Supported values are SHA256 and SHA512. Default to SHA512 arbitrarily. SHA512 is generally faster on 64-bit architectures. On a few arm64 CPUs I tested SHA256 is much faster, but that's most likely because they only support acceleration via FEAT_SHA256 (Armv8.0) and not FEAT_SHA512 (Armv8.2). Future CPUs supporting RME are likely to also support FEAT_SHA512. Cc: Eric Blake Cc: Markus Armbruster Cc: Daniel P. Berrangé Cc: Eduardo Habkost Acked-by: Markus Armbruster Signed-off-by: Jean-Philippe Brucker --- v2->v3: Rename measurement-algorithm --- qapi/qom.json | 20 +++++++++++++++++++- target/arm/kvm-rme.c | 39 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 57 insertions(+), 2 deletions(-) diff --git a/qapi/qom.json b/qapi/qom.json index f982850bca..901ba67634 100644 --- a/qapi/qom.json +++ b/qapi/qom.json @@ -1068,6 +1068,20 @@ 'data': { '*cpu-affinity': ['uint16'], '*node-affinity': ['uint16'] } } +## +# @RmeGuestMeasurementAlgorithm: +# +# @sha256: Use the SHA256 algorithm +# +# @sha512: Use the SHA512 algorithm +# +# Algorithm to use for realm measurements +# +# Since: 9.3 +## +{ 'enum': 'RmeGuestMeasurementAlgorithm', + 'data': ['sha256', 'sha512'] } + ## # @RmeGuestProperties: # @@ -1077,10 +1091,14 @@ # hex string. This optional parameter allows to uniquely identify # the VM instance during attestation. (default: 0) # +# @measurement-algorithm: Realm measurement algorithm +# (default: sha512) +# # Since: 9.3 ## { 'struct': 'RmeGuestProperties', - 'data': { '*personalization-value': 'str' } } + 'data': { '*personalization-value': 'str', + '*measurement-algorithm': 'RmeGuestMeasurementAlgorithm' } } ## # @ObjectType: diff --git a/target/arm/kvm-rme.c b/target/arm/kvm-rme.c index 0be55867ee..bf0bcf9a38 100644 --- a/target/arm/kvm-rme.c +++ b/target/arm/kvm-rme.c @@ -23,7 +23,7 @@ OBJECT_DECLARE_SIMPLE_TYPE(RmeGuest, RME_GUEST) #define RME_PAGE_SIZE qemu_real_host_page_size() -#define RME_MAX_CFG 1 +#define RME_MAX_CFG 2 struct RmeGuest { ConfidentialGuestSupport parent_obj; @@ -31,6 +31,7 @@ struct RmeGuest { GSList *ram_regions; uint8_t *personalization_value; + RmeGuestMeasurementAlgorithm measurement_algo; hwaddr ram_base; size_t ram_size; @@ -63,6 +64,19 @@ static int rme_configure_one(RmeGuest *guest, uint32_t cfg, Error **errp) memcpy(args.rpv, guest->personalization_value, KVM_CAP_ARM_RME_RPV_SIZE); cfg_str = "personalization value"; break; + case KVM_CAP_ARM_RME_CFG_HASH_ALGO: + switch (guest->measurement_algo) { + case RME_GUEST_MEASUREMENT_ALGORITHM_SHA256: + args.hash_algo = KVM_CAP_ARM_RME_MEASUREMENT_ALGO_SHA256; + break; + case RME_GUEST_MEASUREMENT_ALGORITHM_SHA512: + args.hash_algo = KVM_CAP_ARM_RME_MEASUREMENT_ALGO_SHA512; + break; + default: + g_assert_not_reached(); + } + cfg_str = "hash algorithm"; + break; default: g_assert_not_reached(); } @@ -275,12 +289,34 @@ static void rme_set_rpv(Object *obj, const char *value, Error **errp) } } +static int rme_get_measurement_algo(Object *obj, Error **errp) +{ + RmeGuest *guest = RME_GUEST(obj); + + return guest->measurement_algo; +} + +static void rme_set_measurement_algo(Object *obj, int algo, Error **errp) +{ + RmeGuest *guest = RME_GUEST(obj); + + guest->measurement_algo = algo; +} + static void rme_guest_class_init(ObjectClass *oc, void *data) { object_class_property_add_str(oc, "personalization-value", rme_get_rpv, rme_set_rpv); object_class_property_set_description(oc, "personalization-value", "Realm personalization value (512-bit hexadecimal number)"); + + object_class_property_add_enum(oc, "measurement-algorithm", + "RmeGuestMeasurementAlgorithm", + &RmeGuestMeasurementAlgorithm_lookup, + rme_get_measurement_algo, + rme_set_measurement_algo); + object_class_property_set_description(oc, "measurement-algorithm", + "Realm measurement algorithm ('sha256', 'sha512')"); } static void rme_guest_init(Object *obj) @@ -290,6 +326,7 @@ static void rme_guest_init(Object *obj) exit(1); } rme_guest = RME_GUEST(obj); + rme_guest->measurement_algo = RME_GUEST_MEASUREMENT_ALGORITHM_SHA512; } static void rme_guest_finalize(Object *obj) From patchwork Mon Nov 25 19:56:11 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Philippe Brucker X-Patchwork-Id: 13885231 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id BBD1CD59D6A for ; Mon, 25 Nov 2024 20:03:50 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tFfFI-0005B9-I9; Mon, 25 Nov 2024 14:59:44 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tFfFE-00057Y-5M for qemu-devel@nongnu.org; Mon, 25 Nov 2024 14:59:40 -0500 Received: from mail-wm1-x32e.google.com ([2a00:1450:4864:20::32e]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1tFfF7-0004of-Ie for qemu-devel@nongnu.org; Mon, 25 Nov 2024 14:59:39 -0500 Received: by mail-wm1-x32e.google.com with SMTP id 5b1f17b1804b1-4349e4e252dso14143545e9.0 for ; Mon, 25 Nov 2024 11:59:33 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1732564771; x=1733169571; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=RVDgLJZAGkfB+8H1cL/Q3uYqegohVBa+MtPvms4CCZc=; b=UCtL3JwmdrieI5FheeyJF5KI/caoRzLSBP7aYd+d8UjoRQNTpTTDhU0n47A+JLTdTy VYKnwfpebHgLSL9hC2RgWtHhhdZ8qoa8h2Nv5QUKcWJ2f4e9inKBBi/GG086xHgfUIpB SMX4XIpKt58TIZWwCQ4lfYk02YQjD6HipChpg7w2ZdfNjlakDzm/C3bQcFLrGtUFFl1/ JsEEeBDKnIzKZqwIi0Z73UHCVlycWnN8ilgKYZs70kkLklrmJP8vfG67Gt+5KvGWmPrW 4DCiv2dVabZ0jahXOyQk4wlBmboht2f5eFGmUJGEwXknxFSnkTgNGUcoAq11f+QJzTJa zjvA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1732564771; x=1733169571; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=RVDgLJZAGkfB+8H1cL/Q3uYqegohVBa+MtPvms4CCZc=; b=v77+6oiL+1YeIJ3W5ZJdov9Sv9nYTTjxxtNlKG24zaAO2uczLVPHldn35niPwiQLtg CMhfv2vzzpq7F0/1yTW5jWyLyFreEnQ4/7AIZMs7b01JmQA3l3IyYIOxl+Ta+jNWrpqx yfioL1690XCqQTs7fdssoME7yDz+uLLfPVkHgNmObHQ1fjRTu2ooJCPG0OA3aMhSgd+s wtEeHAbqVHdQOt4ievFcWsZExCa+8EOdWR27nEGtZ40lQE4BnwVlAg0QxZLo0Z+xUGRC ZhD2OhpkbmZsvs076Mou2o67KoXLyndP16oP573S+4fD9Uw3vzCNEmcvf0hkKZ3oJVJW KBig== X-Forwarded-Encrypted: i=1; AJvYcCWyWBnlDrFXxRR8ShpueWjaE0Kh0oe5R+e90Jr+NCh6KUktDWCAvA6C5/rW122vAf1wZcbkxLAxJuDF@nongnu.org X-Gm-Message-State: AOJu0YxK9J1zVJh3JjNV0IkC0c22OSvYifQshUZZ0ccUgT38gymSDUoP iETi4JyYVRKkYOnI/MU9N0BnI5aUpotxNz85lLhJ7v+9Hy7W83cDxYyWNbs2OyE= X-Gm-Gg: ASbGncuNoNTSOp1b502C1AN2ksPJ69pCq6G4UdfTgKYyaKoFjjrJYJhImjbthFmGWSU am4NwJyAw32pM3z40x92TSw9Rqt46auZ1aJrd4kimYewT+yaobRVrPQecDJGNn/qQKj9hvMoBW6 0cniEd6IJk1Kgmwk6rz+90Kx8oM7OKjZb6njaOlkdtsa0ImWqkRoiJVh0xAqgbpSgqU11iJn6R+ ESn6haCeY//ul5/rPmoES5zLRZ2RDDIAgW2MsxEmjpdPOrxXNo/VmWLdafPFN2YXami X-Google-Smtp-Source: AGHT+IEaC1ttBSm2FtMlk4y0oHvFOQX7SKISqb0ItjMzkK9PFyhTNsAw3VpBr4qH7Z44KcuwSkVF0w== X-Received: by 2002:a05:600c:510b:b0:431:1d97:2b0a with SMTP id 5b1f17b1804b1-433ce42875cmr136065045e9.15.1732564771511; Mon, 25 Nov 2024 11:59:31 -0800 (PST) Received: from localhost.localdomain ([2.221.137.100]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3825fd0fbdcsm11237971f8f.109.2024.11.25.11.59.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 25 Nov 2024 11:59:31 -0800 (PST) From: Jean-Philippe Brucker To: peter.maydell@linaro.org Cc: richard.henderson@linaro.org, philmd@linaro.org, qemu-arm@nongnu.org, qemu-devel@nongnu.org, alex.bennee@linaro.org, Jean-Philippe Brucker Subject: [PATCH v3 12/26] target/arm/cpu: Set number of breakpoints and watchpoints in KVM Date: Mon, 25 Nov 2024 19:56:11 +0000 Message-ID: <20241125195626.856992-14-jean-philippe@linaro.org> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241125195626.856992-2-jean-philippe@linaro.org> References: <20241125195626.856992-2-jean-philippe@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::32e; envelope-from=jean-philippe@linaro.org; helo=mail-wm1-x32e.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Add "num-breakpoints" and "num-watchpoints" CPU parameters to configure the debug features that KVM presents to the guest. The KVM vCPU configuration is modified by calling SET_ONE_REG on the ID register. This is needed for Realm VMs, whose parameters include breakpoints and watchpoints, and influence the Realm Initial Measurement. Signed-off-by: Jean-Philippe Brucker --- target/arm/cpu.h | 4 ++ target/arm/kvm_arm.h | 2 + target/arm/arm-qmp-cmds.c | 1 + target/arm/cpu64.c | 77 +++++++++++++++++++++++++++++++++++++++ target/arm/kvm.c | 56 +++++++++++++++++++++++++++- 5 files changed, 139 insertions(+), 1 deletion(-) diff --git a/target/arm/cpu.h b/target/arm/cpu.h index f617591921..5cef43a8d2 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -1109,6 +1109,10 @@ struct ArchCPU { /* Generic timer counter frequency, in Hz */ uint64_t gt_cntfrq_hz; + + /* Allows to override the default configuration */ + uint8_t num_bps; + uint8_t num_wps; }; typedef struct ARMCPUInfo { diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h index 67db09a424..28ebec8580 100644 --- a/target/arm/kvm_arm.h +++ b/target/arm/kvm_arm.h @@ -16,6 +16,8 @@ #define KVM_ARM_VGIC_V2 (1 << 0) #define KVM_ARM_VGIC_V3 (1 << 1) +#define KVM_REG_ARM_ID_AA64DFR0_EL1 ARM64_SYS_REG(3, 0, 0, 5, 0) + /** * kvm_arm_register_device: * @mr: memory region for this device diff --git a/target/arm/arm-qmp-cmds.c b/target/arm/arm-qmp-cmds.c index 3cc8cc738b..0f574bb1dd 100644 --- a/target/arm/arm-qmp-cmds.c +++ b/target/arm/arm-qmp-cmds.c @@ -95,6 +95,7 @@ static const char *cpu_model_advertised_features[] = { "sve1408", "sve1536", "sve1664", "sve1792", "sve1920", "sve2048", "kvm-no-adjvtime", "kvm-steal-time", "pauth", "pauth-impdef", "pauth-qarma3", + "num-breakpoints", "num-watchpoints", NULL }; diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c index 458d1cee01..1d4f4c134d 100644 --- a/target/arm/cpu64.c +++ b/target/arm/cpu64.c @@ -576,6 +576,82 @@ void aarch64_add_pauth_properties(Object *obj) } } +#if defined(CONFIG_KVM) +static void arm_cpu_get_num_wps(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) +{ + uint8_t val; + ARMCPU *cpu = ARM_CPU(obj); + + val = cpu->num_wps; + if (val == 0) { + val = FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, WRPS) + 1; + } + + visit_type_uint8(v, name, &val, errp); +} + +static void arm_cpu_set_num_wps(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) +{ + uint8_t val; + ARMCPU *cpu = ARM_CPU(obj); + uint8_t max_wps = FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, WRPS) + 1; + + if (!visit_type_uint8(v, name, &val, errp)) { + return; + } + + if (val < 2 || val > max_wps) { + error_setg(errp, "invalid number of watchpoints"); + return; + } + + cpu->num_wps = val; +} + +static void arm_cpu_get_num_bps(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) +{ + uint8_t val; + ARMCPU *cpu = ARM_CPU(obj); + + val = cpu->num_bps; + if (val == 0) { + val = FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, BRPS) + 1; + } + + visit_type_uint8(v, name, &val, errp); +} + +static void arm_cpu_set_num_bps(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) +{ + uint8_t val; + ARMCPU *cpu = ARM_CPU(obj); + uint8_t max_bps = FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, BRPS) + 1; + + if (!visit_type_uint8(v, name, &val, errp)) { + return; + } + + if (val < 2 || val > max_bps) { + error_setg(errp, "invalid number of breakpoints"); + return; + } + + cpu->num_bps = val; +} + +static void aarch64_add_kvm_writable_properties(Object *obj) +{ + object_property_add(obj, "num-breakpoints", "uint8", arm_cpu_get_num_bps, + arm_cpu_set_num_bps, NULL, NULL); + object_property_add(obj, "num-watchpoints", "uint8", arm_cpu_get_num_wps, + arm_cpu_set_num_wps, NULL, NULL); +} +#endif /* CONFIG_KVM */ + void arm_cpu_lpa2_finalize(ARMCPU *cpu, Error **errp) { uint64_t t; @@ -726,6 +802,7 @@ static void aarch64_host_initfn(Object *obj) if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) { aarch64_add_sve_properties(obj); aarch64_add_pauth_properties(obj); + aarch64_add_kvm_writable_properties(obj); } #elif defined(CONFIG_HVF) ARMCPU *cpu = ARM_CPU(obj); diff --git a/target/arm/kvm.c b/target/arm/kvm.c index 870f51bf02..f6d45476b4 100644 --- a/target/arm/kvm.c +++ b/target/arm/kvm.c @@ -336,7 +336,7 @@ static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64smfr0, ARM64_SYS_REG(3, 0, 0, 4, 5)); err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64dfr0, - ARM64_SYS_REG(3, 0, 0, 5, 0)); + KVM_REG_ARM_ID_AA64DFR0_EL1); err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64dfr1, ARM64_SYS_REG(3, 0, 0, 5, 1)); err |= read_sys_reg64(fdarray[2], &ahcf->isar.id_aa64isar0, @@ -887,6 +887,54 @@ out: return ret; } +static void kvm_arm_configure_aa64dfr0(ARMCPU *cpu) +{ + int ret; + uint64_t val, newval; + CPUState *cs = CPU(cpu); + + if (!cpu->num_bps && !cpu->num_wps) { + return; + } + + newval = cpu->isar.id_aa64dfr0; + if (cpu->num_bps) { + uint64_t ctx_cmps = FIELD_EX64(newval, ID_AA64DFR0, CTX_CMPS); + + /* CTX_CMPs is never greater than BRPs */ + ctx_cmps = MIN(ctx_cmps, cpu->num_bps - 1); + newval = FIELD_DP64(newval, ID_AA64DFR0, BRPS, cpu->num_bps - 1); + newval = FIELD_DP64(newval, ID_AA64DFR0, CTX_CMPS, ctx_cmps); + } + if (cpu->num_wps) { + newval = FIELD_DP64(newval, ID_AA64DFR0, WRPS, cpu->num_wps - 1); + } + ret = kvm_set_one_reg(cs, KVM_REG_ARM_ID_AA64DFR0_EL1, &newval); + if (ret) { + error_report("Failed to set KVM_REG_ARM_ID_AA64DFR0_EL1"); + return; + } + + /* + * Check if the write succeeded. KVM does offer the writable mask for this + * register, but this way we also check if the value we wrote was sane. + */ + ret = kvm_get_one_reg(cs, KVM_REG_ARM_ID_AA64DFR0_EL1, &val); + if (ret) { + error_report("Failed to get KVM_REG_ARM_ID_AA64DFR0_EL1"); + return; + } + + if (val != newval) { + error_report("Failed to update KVM_REG_ARM_ID_AA64DFR0_EL1"); + } +} + +static void kvm_arm_configure_vcpu_regs(ARMCPU *cpu) +{ + kvm_arm_configure_aa64dfr0(cpu); +} + /** * kvm_arm_cpreg_level: * @regidx: KVM register index @@ -1006,6 +1054,12 @@ void kvm_arm_reset_vcpu(ARMCPU *cpu) fprintf(stderr, "kvm_arm_vcpu_init failed: %s\n", strerror(-ret)); abort(); } + + /* + * Before loading the KVM values into CPUState, update the KVM configuration + */ + kvm_arm_configure_vcpu_regs(cpu); + if (!write_kvmstate_to_list(cpu)) { fprintf(stderr, "write_kvmstate_to_list failed\n"); abort(); From patchwork Mon Nov 25 19:56:12 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Philippe Brucker X-Patchwork-Id: 13885224 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 9EF0FD59D6A for ; Mon, 25 Nov 2024 20:02:12 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tFfFJ-0005D0-FK; Mon, 25 Nov 2024 14:59:45 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tFfFE-000589-Rz for qemu-devel@nongnu.org; Mon, 25 Nov 2024 14:59:40 -0500 Received: from mail-wm1-x334.google.com ([2a00:1450:4864:20::334]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1tFfF7-0004pB-Im for qemu-devel@nongnu.org; Mon, 25 Nov 2024 14:59:40 -0500 Received: by mail-wm1-x334.google.com with SMTP id 5b1f17b1804b1-434a0fd9778so9456385e9.0 for ; Mon, 25 Nov 2024 11:59:33 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1732564772; x=1733169572; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=+ZxFPU/cHWqHSELYlJR67QZcEPKYi6vUTmv//JrZID4=; b=Z61uNxaBekoD6oSz6xG0+5RfnGFEFtjB/q0VT7ABSKHKl6uLMzI2jhSpvQShmKeaWR Fh56Z6pfzyjigWIcxchhDyu8ZGbwKsNhZhksYBf0vJt183pSJkAbg6KkP6LTlDQWlJl0 +m5um7qbztjXaXnyA7P8TFqrQIp1Gc59cry1nlfK1Mp6jdgMw8+8y4/NRp0IYboMpVlo /TktK+dmzml4D4JF08RiwvhZL7GnKDsKNHsmWGptK3NX7z9db6915tfshD22C6PgIWd/ mepkOgs48gpflmtNCUbXw0opJYxVay9oHs7fMGvbCfZNsU932Irpo0uNtHlkx4ynoRWu LYEA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1732564772; x=1733169572; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=+ZxFPU/cHWqHSELYlJR67QZcEPKYi6vUTmv//JrZID4=; b=dpy2I0ACx4Xd83EnE3FCHGxdlwGPhvE+5QX5OVUx8v9Go/u6BMEhFYgEIdX2cahyCl qCFDkDMRqDXzvbRi4pF7p/5tjczOIgnflufKRvLgj6EQPvUwAxPYaNr5N2cX1MdhgPCo wx0e5M6miaHvV8TjcZ8Hw7TRhvk+5q4UHtVF6U2iT4L78u0powXg62dB1cN4g+Zh96jY xcT7LluuRGZ0SXCSnp0ovfG73886SL7sC6aXXgrA+xOpFs9VUNsQaTm3OZtndI7uXPEG ktKALjhPb5kSuZnBYFkxHWjRa+gHZVH2ue6wS0oPCgZRfmmZoDqTglMZ688dlfaPmSSl 2HRA== X-Forwarded-Encrypted: i=1; AJvYcCXnpu1Um4A5IGcfPY+XejUnbLO1i7extD/Tb5mdj87rHu3ByaIeI+gEqH7ND8/j5guP7sn5Mndspk8M@nongnu.org X-Gm-Message-State: AOJu0Yz6DssmIPdgKYGcpJNgD1U35dxveD4geJ40yjCu7cyovdcROOuu WCxzaSjzgsIvm2ohzxAm5a94qkh9ybrYcEgUTenC7gNM1aWWJMnnsn/oy8QlRsU= X-Gm-Gg: ASbGncvgo48FBnk4uOz8ijNfo+JT2FQnfYYJtOLl6m/JMKbKwuKGDAKRmm/rRGm3vYx zCO4Zhsn3JrXy84rnH8/aI0lxcmwsuWB2WWBaQBSz0afp31TgyEj3B3n77NgwSX4G2ku4Cc0FJ1 Pe/BxfcsLYJEePkTObpdpdKpeYcJU7cj/7SvHeuhuy5oAEQHKofyt5DHKJvDSFbvdPTTwy/p10r wJlrGzqFLrx5lrFZDGyiV/4nyjyS+/cZnvnkPETrFFWKwMlbLAux5YDpti2b4mDwoir X-Google-Smtp-Source: AGHT+IFVuKUMl8qVl+jZythLFRNH6SVTB2gdvNX8aguLJeAEaTVKDcV1J7mB6Tu6aoTmT/NUzj/bDQ== X-Received: by 2002:a05:600c:4f86:b0:431:5632:448b with SMTP id 5b1f17b1804b1-433ce48eb82mr109983075e9.25.1732564772013; Mon, 25 Nov 2024 11:59:32 -0800 (PST) Received: from localhost.localdomain ([2.221.137.100]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3825fd0fbdcsm11237971f8f.109.2024.11.25.11.59.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 25 Nov 2024 11:59:31 -0800 (PST) From: Jean-Philippe Brucker To: peter.maydell@linaro.org Cc: richard.henderson@linaro.org, philmd@linaro.org, qemu-arm@nongnu.org, qemu-devel@nongnu.org, alex.bennee@linaro.org, Jean-Philippe Brucker Subject: [PATCH v3 13/26] target/arm/cpu: Set number of PMU counters in KVM Date: Mon, 25 Nov 2024 19:56:12 +0000 Message-ID: <20241125195626.856992-15-jean-philippe@linaro.org> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241125195626.856992-2-jean-philippe@linaro.org> References: <20241125195626.856992-2-jean-philippe@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::334; envelope-from=jean-philippe@linaro.org; helo=mail-wm1-x334.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Add a "num-pmu-counters" CPU parameter to configure the number of counters that KVM presents to the guest. This is needed for Realm VMs, whose parameters include the number of PMU counters and influence the Realm Initial Measurement. Signed-off-by: Jean-Philippe Brucker --- target/arm/cpu.h | 3 +++ target/arm/kvm_arm.h | 1 + target/arm/arm-qmp-cmds.c | 2 +- target/arm/cpu64.c | 41 +++++++++++++++++++++++++++++++++++++++ target/arm/kvm.c | 34 +++++++++++++++++++++++++++++++- 5 files changed, 79 insertions(+), 2 deletions(-) diff --git a/target/arm/cpu.h b/target/arm/cpu.h index 5cef43a8d2..382dd4ded9 100644 --- a/target/arm/cpu.h +++ b/target/arm/cpu.h @@ -1113,6 +1113,7 @@ struct ArchCPU { /* Allows to override the default configuration */ uint8_t num_bps; uint8_t num_wps; + int8_t num_pmu_ctrs; }; typedef struct ARMCPUInfo { @@ -2393,6 +2394,8 @@ FIELD(MFAR, FPA, 12, 40) FIELD(MFAR, NSE, 62, 1) FIELD(MFAR, NS, 63, 1) +FIELD(PMCR, N, 11, 5) + QEMU_BUILD_BUG_ON(ARRAY_SIZE(((ARMCPU *)0)->ccsidr) <= R_V7M_CSSELR_INDEX_MASK); /* If adding a feature bit which corresponds to a Linux ELF diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h index 28ebec8580..77680f238a 100644 --- a/target/arm/kvm_arm.h +++ b/target/arm/kvm_arm.h @@ -17,6 +17,7 @@ #define KVM_ARM_VGIC_V3 (1 << 1) #define KVM_REG_ARM_ID_AA64DFR0_EL1 ARM64_SYS_REG(3, 0, 0, 5, 0) +#define KVM_REG_ARM_PMCR_EL0 ARM64_SYS_REG(3, 3, 9, 12, 0) /** * kvm_arm_register_device: diff --git a/target/arm/arm-qmp-cmds.c b/target/arm/arm-qmp-cmds.c index 0f574bb1dd..985d4270b8 100644 --- a/target/arm/arm-qmp-cmds.c +++ b/target/arm/arm-qmp-cmds.c @@ -95,7 +95,7 @@ static const char *cpu_model_advertised_features[] = { "sve1408", "sve1536", "sve1664", "sve1792", "sve1920", "sve2048", "kvm-no-adjvtime", "kvm-steal-time", "pauth", "pauth-impdef", "pauth-qarma3", - "num-breakpoints", "num-watchpoints", + "num-breakpoints", "num-watchpoints", "num-pmu-counters", NULL }; diff --git a/target/arm/cpu64.c b/target/arm/cpu64.c index 1d4f4c134d..cf1d17fb90 100644 --- a/target/arm/cpu64.c +++ b/target/arm/cpu64.c @@ -643,12 +643,53 @@ static void arm_cpu_set_num_bps(Object *obj, Visitor *v, const char *name, cpu->num_bps = val; } +static void arm_cpu_get_num_pmu_ctrs(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) +{ + uint8_t val; + ARMCPU *cpu = ARM_CPU(obj); + + if (cpu->num_pmu_ctrs == -1) { + val = FIELD_EX64(cpu->isar.reset_pmcr_el0, PMCR, N); + } else { + val = cpu->num_pmu_ctrs; + } + + visit_type_uint8(v, name, &val, errp); +} + +static void arm_cpu_set_num_pmu_ctrs(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) +{ + uint8_t val; + ARMCPU *cpu = ARM_CPU(obj); + uint8_t max_ctrs = FIELD_EX64(cpu->isar.reset_pmcr_el0, PMCR, N); + + if (!visit_type_uint8(v, name, &val, errp)) { + return; + } + + if (val > max_ctrs) { + error_setg(errp, "invalid number of PMU counters"); + return; + } + + cpu->num_pmu_ctrs = val; +} + static void aarch64_add_kvm_writable_properties(Object *obj) { + ARMCPU *cpu = ARM_CPU(obj); + object_property_add(obj, "num-breakpoints", "uint8", arm_cpu_get_num_bps, arm_cpu_set_num_bps, NULL, NULL); object_property_add(obj, "num-watchpoints", "uint8", arm_cpu_get_num_wps, arm_cpu_set_num_wps, NULL, NULL); + + cpu->num_pmu_ctrs = -1; + object_property_add(obj, "num-pmu-counters", "uint8", + arm_cpu_get_num_pmu_ctrs, arm_cpu_set_num_pmu_ctrs, + NULL, NULL); } #endif /* CONFIG_KVM */ diff --git a/target/arm/kvm.c b/target/arm/kvm.c index f6d45476b4..9784c47ff5 100644 --- a/target/arm/kvm.c +++ b/target/arm/kvm.c @@ -438,7 +438,7 @@ static bool kvm_arm_get_host_cpu_features(ARMHostCPUFeatures *ahcf) if (pmu_supported) { /* PMCR_EL0 is only accessible if the vCPU has feature PMU_V3 */ err |= read_sys_reg64(fdarray[2], &ahcf->isar.reset_pmcr_el0, - ARM64_SYS_REG(3, 3, 9, 12, 0)); + KVM_REG_ARM_PMCR_EL0); } if (sve_supported) { @@ -930,9 +930,41 @@ static void kvm_arm_configure_aa64dfr0(ARMCPU *cpu) } } +static void kvm_arm_configure_pmcr(ARMCPU *cpu) +{ + int ret; + uint64_t val, newval; + CPUState *cs = CPU(cpu); + + if (cpu->num_pmu_ctrs == -1) { + return; + } + + newval = FIELD_DP64(cpu->isar.reset_pmcr_el0, PMCR, N, cpu->num_pmu_ctrs); + ret = kvm_set_one_reg(cs, KVM_REG_ARM_PMCR_EL0, &newval); + if (ret) { + error_report("Failed to set KVM_REG_ARM_PMCR_EL0"); + return; + } + + /* + * Check if the write succeeded, since older versions of KVM ignore it. + */ + ret = kvm_get_one_reg(cs, KVM_REG_ARM_PMCR_EL0, &val); + if (ret) { + error_report("Failed to get KVM_REG_ARM_PMCR_EL0"); + return; + } + + if (val != newval) { + error_report("Failed to update KVM_REG_ARM_PMCR_EL0"); + } +} + static void kvm_arm_configure_vcpu_regs(ARMCPU *cpu) { kvm_arm_configure_aa64dfr0(cpu); + kvm_arm_configure_pmcr(cpu); } /** From patchwork Mon Nov 25 19:56:13 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Philippe Brucker X-Patchwork-Id: 13885234 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 778CDD59D69 for ; Mon, 25 Nov 2024 20:04:43 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tFfFI-0005B3-FY; Mon, 25 Nov 2024 14:59:44 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tFfFF-00058N-6q for qemu-devel@nongnu.org; Mon, 25 Nov 2024 14:59:41 -0500 Received: from mail-wr1-x436.google.com ([2a00:1450:4864:20::436]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1tFfF8-0004pX-4Q for qemu-devel@nongnu.org; Mon, 25 Nov 2024 14:59:40 -0500 Received: by mail-wr1-x436.google.com with SMTP id ffacd0b85a97d-37ed3bd6114so2872679f8f.2 for ; Mon, 25 Nov 2024 11:59:33 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1732564772; x=1733169572; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=NexLDu9BoTuLD1ACg75BFq2LpMIPfdBrbSTr833QRX8=; b=cFWcANs9YwBOXZ58AiNJerJjajQ5GWidvxPMsiXsyTlNbN4mnmUz8jUz0eRpBcFm8/ scJNirajSjjNxQiHGZUnATxPx8hLW+jCJKy4QRoKW/t9J1qhgyYT86wbuy7zxmR+R7ML I907u615g9gVakgdGACPcYlD3XHTCJ7SwKsptw7SOUlwKRkLdmLlM/Q7jQfWNNlEbFXb rQZx2eIFZurKiRpE7+XsBI7EVtaohsEJBQiaewbfIV4AqTqU8aNt35NP+NwuPEss7dGC 2h0AcFU0JjITAE5dXqiaKbIRmOgDf9iP64VPOLE/lL0rYahk2dAhUYt0hD/rCo+jEmpn LT/g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1732564772; x=1733169572; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=NexLDu9BoTuLD1ACg75BFq2LpMIPfdBrbSTr833QRX8=; b=AZZjmfdB/63SmxRciqXE66AhhjXnjrdyiDOAhDQ8wz1mkb0nuMiwe+AfBfAF4KqOo8 B+774YndYCkq2Sac06poxV9nh4YtXSyBrwiuzkE5kHL7AMkYniZUnUvRgK4/Ne1+kFPn S6QtMpOLk9JLTgYb2l7Hh1d4dZ0VUbP2yQ3r8u38VxQnHB/Xm23NKHKx9Koz3jcgnmmV CBQV6Zr+W+RKEOIUAFpiOmwJigvHztCjzdhr4pnGn1Wabg5Lj7qgJz2kj7sXneBfQlCW OBTUC+WjZvkweN8C6joc2dpffxOGod8vLs5rjGFx+22c+fi4BAZS3ECG1qikj+tCus7A cZXA== X-Forwarded-Encrypted: i=1; AJvYcCXPSy2xEByVW7hxSu9qqU2LcnYi5kq5euINcBY7EuNbPsnPkES+iZarwUfKu7kzNOkzofQ/Eofi8Jpl@nongnu.org X-Gm-Message-State: AOJu0Yz5XtJE3Kkegd5AnyFjYaK2vqwDmdsu3LcdbTjEnghRi78Bo10Z QBgnTZL2/wDHG5nCFDP+WxZTQDPrC/bvs40J6PCnsLvJoI0L/U0ZBsjFuzjuVzA= X-Gm-Gg: ASbGncthXKt8c8hv8EdBgFMOS1np3O7EAcXOHF1XhG+AepfTEyOpcnL+CT5s55rNwgf 5dHKatDSJ9U2ygVyfE4e1CKWMn+Lj8qp2pMdIxdE27zGRiY0uxLi1ep+6mNtwkspCX51YlrDwff 42tCDcb+iOWZaIP1d1H7YwnYQihgaRex7USZvjo8qSVdYqLOyI957SXzPT0OZH0qLcBykLYcG4r l/zvFXyN120sH18s8vGYA+l+Oh5XF143uDTwr47U7UAE5Ml2N7yKYO/7bhTQ3a2368m X-Google-Smtp-Source: AGHT+IFCPZLjADcW8fIg/RWkYEbvN1XaUQSM0f35LENvp2ikPkmmonU9r3fcgb+nDIAWPkH3+0dnyQ== X-Received: by 2002:a05:6000:4813:b0:382:134d:65e0 with SMTP id ffacd0b85a97d-38260be5f63mr13089017f8f.56.1732564772667; Mon, 25 Nov 2024 11:59:32 -0800 (PST) Received: from localhost.localdomain ([2.221.137.100]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3825fd0fbdcsm11237971f8f.109.2024.11.25.11.59.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 25 Nov 2024 11:59:32 -0800 (PST) From: Jean-Philippe Brucker To: peter.maydell@linaro.org Cc: richard.henderson@linaro.org, philmd@linaro.org, qemu-arm@nongnu.org, qemu-devel@nongnu.org, alex.bennee@linaro.org, Jean-Philippe Brucker Subject: [PATCH v3 14/26] target/arm/cpu: Inform about reading confidential CPU registers Date: Mon, 25 Nov 2024 19:56:13 +0000 Message-ID: <20241125195626.856992-16-jean-philippe@linaro.org> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241125195626.856992-2-jean-philippe@linaro.org> References: <20241125195626.856992-2-jean-philippe@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::436; envelope-from=jean-philippe@linaro.org; helo=mail-wr1-x436.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org The host cannot access registers of a Realm. Instead of showing all registers as zero in "info registers", display a message about this restriction. Signed-off-by: Jean-Philippe Brucker --- target/arm/cpu.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/target/arm/cpu.c b/target/arm/cpu.c index 6938161b95..7f6569e87e 100644 --- a/target/arm/cpu.c +++ b/target/arm/cpu.c @@ -1232,6 +1232,11 @@ static void aarch64_cpu_dump_state(CPUState *cs, FILE *f, int flags) const char *ns_status; bool sve; + if (cpu->kvm_rme) { + qemu_fprintf(f, "the CPU registers are confidential to the realm\n"); + return; + } + qemu_fprintf(f, " PC=%016" PRIx64 " ", env->pc); for (i = 0; i < 32; i++) { if (i == 31) { From patchwork Mon Nov 25 19:56:14 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Philippe Brucker X-Patchwork-Id: 13885237 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 8640AD59D67 for ; Mon, 25 Nov 2024 20:04:59 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tFfFL-0005FX-Bc; Mon, 25 Nov 2024 14:59:47 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tFfFF-00058c-Sr for qemu-devel@nongnu.org; Mon, 25 Nov 2024 14:59:41 -0500 Received: from mail-wr1-x42f.google.com ([2a00:1450:4864:20::42f]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1tFfF8-0004px-NE for qemu-devel@nongnu.org; Mon, 25 Nov 2024 14:59:41 -0500 Received: by mail-wr1-x42f.google.com with SMTP id ffacd0b85a97d-382442b7d9aso3702352f8f.1 for ; Mon, 25 Nov 2024 11:59:34 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1732564773; x=1733169573; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=AM9CmiES+peuGOYCBRYh0Z2NclowtBsfFXloH3BjlTc=; b=dRHjC29qNV+eJt2DmKU5jbWE15eyykMPIar8TDdP2GfBR7jO/6YP8lVAPC7+MneffB Xpbc9eIT+onE8l0IRMiyGcB5TleQt6CdOF2uWbMK43oSB6BI7flTT9vvm8wnXxKhjew8 MNEIN2f0/eiSmbEem6wt8tiwH3stoQcRMSmEM8+bV1Inh6GDe6hUfvZhjARqoMI62MxD YuWkMEbbwQJ9GoDheI1ErjxcFyrnH4b/qQKJXA/bNRf0O99K6WxzbJGOpTNY9rO8gvZQ C2HPsFr+nNeyWMBFiN9qEDJbqgOLyEFPXeRXFb7w50xqVk/Xe5ZaTcTrbsPCBVG5rb4O 5H/g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1732564773; x=1733169573; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=AM9CmiES+peuGOYCBRYh0Z2NclowtBsfFXloH3BjlTc=; b=cUIHsMDFMn1zza5gvgM78lWkMmk9m2mHLYeIx9HzM8W3/OC3GnnpWbqu2kBbJLPT/8 MN0/E1NOYURwvaK2Brxn/ij8VKBcCMhrOU17dGVt9EHaMhhCG1OHs174UeafEsuwHedA BgqEuz9KFJHDGyVJhCJ4uPRPQekpOlojF8cblBaZ+YVGWMuCCtjGJxOvLk9uHIjp1Go9 vy5Ta+PFRZ3vF2VboH6G95g9Zy1c4L8pSlikoulcwXrp5WfAzgxIS2KsMuBRC45X6Lxo t6dI+oCpzvPYv/ui68J+DITmz4cnCcAbTYdDhP4dQr3UL10kGAxLEIiY4c9ugBLkKvrF r23w== X-Forwarded-Encrypted: i=1; AJvYcCUwtiZdRX6ycpg5zEFFhBRwQKmDc8uCg382W5ZIsiiOpd+uP0XSTYMtuzbzyaHqWDSAfut/A5kMtRSJ@nongnu.org X-Gm-Message-State: AOJu0YzBTpPkLr+cUnJWeZZPGHS4/SDTVUDdu4ZQU2SU7Tzv5Cl6dVVn U75p+UX/H+Vf7sNuaAfh0+UFBlOAoG+vdmH8WSrsv2twOJdSrdglBgnqbLw5XSI= X-Gm-Gg: ASbGncu0cDosYGSNC/l6uFGgizCUN2PDacUrzosggNOW3UksvcooEnFNklARxatfyFC jDZOcnoPxroz9e0k9B7YG7aTrwCTISox+7xn5aJ68YedY/hNIQZ70fQfnPv0wNzJUul/iYrUkwB 7kmIemubhGqiFlSGKH94pKyc+Fj16vXRAwNaa1xZgYTW3vISBt8ROwwOgBXOUh28nG9XMfSvLwa K9/tEz6gu+offhPWyVBI+Eqc7U3Psam3OqQf9S7po2qH1iZvo0lt81rt20qx+NiAQXO X-Google-Smtp-Source: AGHT+IG8nC95KgxPOV4gNNszZYNmR7epAcoJPgXz8ijIjcuMTQZVqQBxAAlIVhMM0m+tNLQY0PCvEQ== X-Received: by 2002:a05:6000:2ae:b0:382:4378:4652 with SMTP id ffacd0b85a97d-38260bcb8b4mr11780186f8f.45.1732564773213; Mon, 25 Nov 2024 11:59:33 -0800 (PST) Received: from localhost.localdomain ([2.221.137.100]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3825fd0fbdcsm11237971f8f.109.2024.11.25.11.59.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 25 Nov 2024 11:59:32 -0800 (PST) From: Jean-Philippe Brucker To: peter.maydell@linaro.org Cc: richard.henderson@linaro.org, philmd@linaro.org, qemu-arm@nongnu.org, qemu-devel@nongnu.org, alex.bennee@linaro.org, Jean-Philippe Brucker Subject: [PATCH v3 15/26] hw/arm/virt: Add support for Arm RME Date: Mon, 25 Nov 2024 19:56:14 +0000 Message-ID: <20241125195626.856992-17-jean-philippe@linaro.org> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241125195626.856992-2-jean-philippe@linaro.org> References: <20241125195626.856992-2-jean-philippe@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::42f; envelope-from=jean-philippe@linaro.org; helo=mail-wr1-x42f.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org When confidential-guest-support is enabled for the virt machine, add the RME flag to the VM type. The HVC conduit for PSCI is not supported for Realms. Signed-off-by: Jean-Philippe Brucker --- hw/arm/virt.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 1a381e9a2b..2d36640733 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -229,6 +229,11 @@ static const int a15irqmap[] = { [VIRT_PLATFORM_BUS] = 112, /* ...to 112 + PLATFORM_BUS_NUM_IRQS -1 */ }; +static bool virt_machine_is_confidential(VirtMachineState *vms) +{ + return MACHINE(vms)->cgs; +} + static void create_randomness(MachineState *ms, const char *node) { struct { @@ -2165,10 +2170,11 @@ static void machvirt_init(MachineState *machine) * if the guest has EL2 then we will use SMC as the conduit, * and otherwise we will use HVC (for backwards compatibility and * because if we're using KVM then we must use HVC). + * Realm guests must also use SMC. */ if (vms->secure && firmware_loaded) { vms->psci_conduit = QEMU_PSCI_CONDUIT_DISABLED; - } else if (vms->virt) { + } else if (vms->virt || virt_machine_is_confidential(vms)) { vms->psci_conduit = QEMU_PSCI_CONDUIT_SMC; } else { vms->psci_conduit = QEMU_PSCI_CONDUIT_HVC; @@ -3013,6 +3019,7 @@ static HotplugHandler *virt_machine_get_hotplug_handler(MachineState *machine, static int virt_kvm_type(MachineState *ms, const char *type_str) { VirtMachineState *vms = VIRT_MACHINE(ms); + int rme_vm_type = kvm_arm_rme_vm_type(ms); int max_vm_pa_size, requested_pa_size; bool fixed_ipa; @@ -3042,7 +3049,11 @@ static int virt_kvm_type(MachineState *ms, const char *type_str) * the implicit legacy 40b IPA setting, in which case the kvm_type * must be 0. */ - return fixed_ipa ? 0 : requested_pa_size; + if (fixed_ipa) { + return 0; + } + + return requested_pa_size | rme_vm_type; } static int virt_hvf_get_physical_address_range(MachineState *ms) From patchwork Mon Nov 25 19:56:15 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Philippe Brucker X-Patchwork-Id: 13885230 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 03EF9D59D69 for ; Mon, 25 Nov 2024 20:03:50 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tFfFK-0005EM-D0; Mon, 25 Nov 2024 14:59:46 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tFfFG-00058m-B2 for qemu-devel@nongnu.org; Mon, 25 Nov 2024 14:59:42 -0500 Received: from mail-wr1-x42f.google.com ([2a00:1450:4864:20::42f]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1tFfF9-0004qA-6G for qemu-devel@nongnu.org; Mon, 25 Nov 2024 14:59:42 -0500 Received: by mail-wr1-x42f.google.com with SMTP id ffacd0b85a97d-38230ed9baeso3430502f8f.1 for ; Mon, 25 Nov 2024 11:59:34 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1732564774; x=1733169574; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=infJS9DeH0K27lOoLlvsvVDPUOvzl4+LENJg6UezPVw=; b=EutVuyD9pOsvz9ThBgVAQQrYgLOwwq0uR4rEMXNESmTwXdsArjRf2FhAW3e+3tDeN7 8p4PJO5Sy77POzdRlrqPOz/++ke0ismX+0+R4sfG7lsq9yu6+2o8+j9gYDUelALhYiQr WG+4Kq0qpEmu2d+HSG6wi7p5C+ct/uS5Dp4IXhCcc9owyft1pvx817bWraiTJSrMEaK5 3qixjFIg+TMsmVgBRCVS2kXuUzOYMwAvkCpPlochdVxMf4l0aFwbR4sdZrQb9g7iFb7k 9zHxZMG5vjMWVkFWfp4pHDylbowA3/w/O8VDjp168k/fKA3vGKDH0yyXKSfZPwQZn+U4 Kudg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1732564774; x=1733169574; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=infJS9DeH0K27lOoLlvsvVDPUOvzl4+LENJg6UezPVw=; b=dXWNYhpphQsv9lthfoET+xwU0ExxZt6aKCkuFsVbl8N5Py2ikU9OetwtLl7hkryBsz ZQD4DSKSopdc9nKgGm6RkgGJ0jZdL+lC9fa96+55SGALDLWkiUlADTh910piWLES2hAn ges60wmJucsV2c2R/gxlQ5017Vd6LtR++vsd+WSJkf1CCOY8D1/1M3SST1SxI+HC6u4S 4E0mXomWetyVwbFIOQLI1BfCpiWxcLcqzJagRyw46vXPdg36vyV7GwNpiJXqixg9KNfi zjlLx8vmh6vjSZidpWSNYCimtCJjwb7bs5laXMoOc0aseNvgYwivA9yKS0D4ViIbb0sL ze8g== X-Forwarded-Encrypted: i=1; AJvYcCV+AYBcpZcPKMejdIRjWfbvAX9E35c0w+LPwfkuYDu+DSbo0inD+nMe9w/hiJzQ/llxQVrjSjyQ3MCY@nongnu.org X-Gm-Message-State: AOJu0Yy3NjZHVgr27sZ2oYbv0VK9EiByNrVUz2IJUxuKVTedvbGvy4Cu aosDNxZgVQd1NktX1proSttJMdWfUK45H8VFzu/agyvGEKJSfWEYA1rJ5SqAFhg= X-Gm-Gg: ASbGncuddOQv43jEtb0MTNePca3LFaj/C4YUrZNoT0nK73KNobIyP5iIbK8oui9EWKw xIjl08c2Pv0QuEgne3GxFM06AZ7bHmVEiFJiAzO+cqxE3UsKMRbkeAQIIp6TAIcpyIoD7wOUzng kjN2hSjWPveKNN1ZdB/VnpVwSrb6T/hHFiTgQnw6DjS9DhoO04W0EU8Dh80k/7we6sytxx4xYE+ tzdMrRW7KHLjdI5CrxT1q4IAuehNqFGAt2Svmn3WUGfybcTPnVxYliJnzqfYbEPRLVg X-Google-Smtp-Source: AGHT+IFz53X0C41rcCk5XmswOFreoozjR+mCfK83ojYyPfr6ibBWXlpbWCzbCzkSaNhjhYu6BBHmqw== X-Received: by 2002:a05:6000:178a:b0:37c:d11f:c591 with SMTP id ffacd0b85a97d-38260b5ba0amr8944205f8f.17.1732564773787; Mon, 25 Nov 2024 11:59:33 -0800 (PST) Received: from localhost.localdomain ([2.221.137.100]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3825fd0fbdcsm11237971f8f.109.2024.11.25.11.59.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 25 Nov 2024 11:59:33 -0800 (PST) From: Jean-Philippe Brucker To: peter.maydell@linaro.org Cc: richard.henderson@linaro.org, philmd@linaro.org, qemu-arm@nongnu.org, qemu-devel@nongnu.org, alex.bennee@linaro.org, Jean-Philippe Brucker Subject: [PATCH v3 16/26] hw/arm/virt: Disable DTB randomness for confidential VMs Date: Mon, 25 Nov 2024 19:56:15 +0000 Message-ID: <20241125195626.856992-18-jean-philippe@linaro.org> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241125195626.856992-2-jean-philippe@linaro.org> References: <20241125195626.856992-2-jean-philippe@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::42f; envelope-from=jean-philippe@linaro.org; helo=mail-wr1-x42f.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org The dtb-randomness feature, which adds random seeds to the DTB, isn't really compatible with confidential VMs since it randomizes the Realm Initial Measurement. Enabling it is not an error, but it prevents attestation. It also isn't useful to a Realm, which doesn't trust host input. Currently the feature is automatically enabled, unless the user disables it on the command-line. Change it to OnOffAuto, and automatically disable it for confidential VMs, unless the user explicitly enables it. Signed-off-by: Jean-Philippe Brucker --- docs/system/arm/virt.rst | 9 +++++---- include/hw/arm/virt.h | 2 +- hw/arm/virt.c | 41 +++++++++++++++++++++++++--------------- 3 files changed, 32 insertions(+), 20 deletions(-) diff --git a/docs/system/arm/virt.rst b/docs/system/arm/virt.rst index e67e7f0f7c..c8319555a5 100644 --- a/docs/system/arm/virt.rst +++ b/docs/system/arm/virt.rst @@ -176,10 +176,11 @@ dtb-randomness rng-seed and kaslr-seed nodes (in both "/chosen" and "/secure-chosen") to use for features like the random number generator and address space randomisation. The default is - ``on``. You will want to disable it if your trusted boot chain - will verify the DTB it is passed, since this option causes the - DTB to be non-deterministic. It would be the responsibility of - the firmware to come up with a seed and pass it on if it wants to. + ``off`` for confidential VMs, and ``on`` otherwise. You will want + to disable it if your trusted boot chain will verify the DTB it is + passed, since this option causes the DTB to be non-deterministic. + It would be the responsibility of the firmware to come up with a + seed and pass it on if it wants to. dtb-kaslr-seed A deprecated synonym for dtb-randomness. diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h index aca4f8061b..e5e9f67f52 100644 --- a/include/hw/arm/virt.h +++ b/include/hw/arm/virt.h @@ -154,7 +154,7 @@ struct VirtMachineState { bool virt; bool ras; bool mte; - bool dtb_randomness; + OnOffAuto dtb_randomness; bool second_ns_uart_present; OnOffAuto acpi; VirtGICType gic_version; diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 2d36640733..9836dfbdfb 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -264,6 +264,7 @@ static bool ns_el2_virt_timer_present(void) static void create_fdt(VirtMachineState *vms) { + bool dtb_randomness = true; MachineState *ms = MACHINE(vms); int nb_numa_nodes = ms->numa_state->num_nodes; void *fdt = create_device_tree(&vms->fdt_size); @@ -273,6 +274,16 @@ static void create_fdt(VirtMachineState *vms) exit(1); } + /* + * Including random data in the DTB causes random intial measurement on CCA, + * so disable it for confidential VMs. + */ + if (vms->dtb_randomness == ON_OFF_AUTO_OFF || + (vms->dtb_randomness == ON_OFF_AUTO_AUTO && + virt_machine_is_confidential(vms))) { + dtb_randomness = false; + } + ms->fdt = fdt; /* Header */ @@ -294,13 +305,13 @@ static void create_fdt(VirtMachineState *vms) /* /chosen must exist for load_dtb to fill in necessary properties later */ qemu_fdt_add_subnode(fdt, "/chosen"); - if (vms->dtb_randomness) { + if (dtb_randomness) { create_randomness(ms, "/chosen"); } if (vms->secure) { qemu_fdt_add_subnode(fdt, "/secure-chosen"); - if (vms->dtb_randomness) { + if (dtb_randomness) { create_randomness(ms, "/secure-chosen"); } } @@ -2570,18 +2581,21 @@ static void virt_set_its(Object *obj, bool value, Error **errp) vms->its = value; } -static bool virt_get_dtb_randomness(Object *obj, Error **errp) +static void virt_get_dtb_randomness(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) { VirtMachineState *vms = VIRT_MACHINE(obj); + OnOffAuto dtb_randomness = vms->dtb_randomness; - return vms->dtb_randomness; + visit_type_OnOffAuto(v, name, &dtb_randomness, errp); } -static void virt_set_dtb_randomness(Object *obj, bool value, Error **errp) +static void virt_set_dtb_randomness(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) { VirtMachineState *vms = VIRT_MACHINE(obj); - vms->dtb_randomness = value; + visit_type_OnOffAuto(v, name, &vms->dtb_randomness, errp); } static char *virt_get_oem_id(Object *obj, Error **errp) @@ -3253,16 +3267,16 @@ static void virt_machine_class_init(ObjectClass *oc, void *data) "Set on/off to enable/disable " "ITS instantiation"); - object_class_property_add_bool(oc, "dtb-randomness", - virt_get_dtb_randomness, - virt_set_dtb_randomness); + object_class_property_add(oc, "dtb-randomness", "OnOffAuto", + virt_get_dtb_randomness, virt_set_dtb_randomness, + NULL, NULL); object_class_property_set_description(oc, "dtb-randomness", "Set off to disable passing random or " "non-deterministic dtb nodes to guest"); - object_class_property_add_bool(oc, "dtb-kaslr-seed", - virt_get_dtb_randomness, - virt_set_dtb_randomness); + object_class_property_add(oc, "dtb-kaslr-seed", "OnOffAuto", + virt_get_dtb_randomness, virt_set_dtb_randomness, + NULL, NULL); object_class_property_set_description(oc, "dtb-kaslr-seed", "Deprecated synonym of dtb-randomness"); @@ -3333,9 +3347,6 @@ static void virt_instance_init(Object *obj) /* MTE is disabled by default. */ vms->mte = false; - /* Supply kaslr-seed and rng-seed by default */ - vms->dtb_randomness = true; - vms->irqmap = a15irqmap; virt_flash_create(vms); From patchwork Mon Nov 25 19:56:16 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Philippe Brucker X-Patchwork-Id: 13885228 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 44268D59D67 for ; Mon, 25 Nov 2024 20:03:44 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tFfFM-0005Gv-Ux; Mon, 25 Nov 2024 14:59:49 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tFfFG-00058n-Cd for qemu-devel@nongnu.org; Mon, 25 Nov 2024 14:59:42 -0500 Received: from mail-wm1-x329.google.com ([2a00:1450:4864:20::329]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1tFfF9-0004qU-Ls for qemu-devel@nongnu.org; Mon, 25 Nov 2024 14:59:42 -0500 Received: by mail-wm1-x329.google.com with SMTP id 5b1f17b1804b1-434a45f05feso4467105e9.3 for ; Mon, 25 Nov 2024 11:59:35 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1732564774; x=1733169574; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=88wZi6u0Mqk3kSDzeuh2IkFT8p2T9s3ILqB4KFRDi3Y=; b=hETvNF74qAZq/GbILjT55FJGJ0u4OClIyOZ3QKQbIUCrzuybXDINENsjBkHHcNzFh7 /Np1ukBqhEpKZhvqmXBpuCQsbcdnTsc1xk6pEZ9Y8i7fwtQpWUOtdoNe092pxG4GLLCJ yWz2/OK4A/5VMwbfobFPbzrP6SIriI7CUWHkW+xjq9dAPJCZHb6sAOCKtxHSQzEaS6ht KWa/+OAeWNKiZ/Da3vXsTu0jTmszCKculo9rcYOgBisIMcw7ZpSr6QDBgEW4ci6gdJC9 7rem+LqsftFOa1MDbMzOXRmx3mXma80p43IzID0j18g4WOqgRohIusKJj9VEgcXccN3F BoWg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1732564774; x=1733169574; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=88wZi6u0Mqk3kSDzeuh2IkFT8p2T9s3ILqB4KFRDi3Y=; b=RKk8ybdaTNVzUqsjdzHOA/Om59Xl4mFlfoIdWyiX9hXAB5xt+e0JBexXdmd7rFaUza GESAiFMyhV3tP6N8Kgzegt0ss0zRTpAxtyjnzAT2xPilfRBhNo1Xik50yo//PfEmLes4 7prCULn0AcbTBvBU3vqg7gdtsFTShMcQ8EWdnY1ApNk7ITkUf1w33pLfdNIpFnFCe9eE ursSRsxIAqDmJ3w2EG6RaGf92rvN9GrsKCWQe6eRjBAAk8c7dB+rFhm2pxZDq1o305XN W/s6qXxThFRkumpCC6xHGPsqxhK+TVKweKbC16OuRjs/ucyFRv+dBJYBjOu+CV/DBCV7 HX4Q== X-Forwarded-Encrypted: i=1; AJvYcCVLS1I9bOf4urtrS2wakUhzAyxB9X7M1ciQsB9oAyuBMBrNdBDylr7KFJd1W9RcAKRTiu4iyDHCK4bQ@nongnu.org X-Gm-Message-State: AOJu0YwrI5yzfT5CRhYw2sPXEi1ooraE5hhFw1MzWgvbqzzJ93UGKfWL elWGSKq9/A0K2BDQFJB0hhJwwNJ8G+7ZfTg46nm+Ty1XXV/A0N0cHbLk2lSlnHM= X-Gm-Gg: ASbGncu6HGS/WEfDnSeHNBDOohwyGtmEBc1sKrBxZwJO+x+FSHmwHvPVS6lDEihO0yP SK/RM3WFKesOvzyRheMUYmYaeZM8s8Y+u8ZbS8mW+bMZsk8fCFCx7Gc1/P55QOeoyx2KZqpvkxS TYxFtSuJMUAYihsQuzfIYFxD1q5aRESuDC0UVkmcKg2xnjPLLwSR1ceTst/MuqhXXrwUR+m7FW/ QyPkghle+9AadeydEV9IloSAgWydkSwtnwY6hckHiK+fOW6mSY3qQTMfAJdSIuygBAZ X-Google-Smtp-Source: AGHT+IFTlfcnMQ8Q4NF57sJVKIYTBVoT9UNzBHBtzEnmlddW54qtujZLRGCe/OHa5mHxjA4P3prFAA== X-Received: by 2002:a05:6000:1866:b0:382:4921:21b5 with SMTP id ffacd0b85a97d-38260bc6a49mr15718516f8f.43.1732564774327; Mon, 25 Nov 2024 11:59:34 -0800 (PST) Received: from localhost.localdomain ([2.221.137.100]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3825fd0fbdcsm11237971f8f.109.2024.11.25.11.59.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 25 Nov 2024 11:59:34 -0800 (PST) From: Jean-Philippe Brucker To: peter.maydell@linaro.org Cc: richard.henderson@linaro.org, philmd@linaro.org, qemu-arm@nongnu.org, qemu-devel@nongnu.org, alex.bennee@linaro.org, Jean-Philippe Brucker Subject: [PATCH v3 17/26] hw/arm/virt: Reserve one bit of guest-physical address for RME Date: Mon, 25 Nov 2024 19:56:16 +0000 Message-ID: <20241125195626.856992-19-jean-philippe@linaro.org> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241125195626.856992-2-jean-philippe@linaro.org> References: <20241125195626.856992-2-jean-philippe@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::329; envelope-from=jean-philippe@linaro.org; helo=mail-wm1-x329.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org When RME is enabled, the upper GPA bit is used to distinguish protected from unprotected addresses. Reserve it when setting up the guest memory map. Signed-off-by: Jean-Philippe Brucker --- hw/arm/virt.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 9836dfbdfb..eb94997914 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -3035,14 +3035,24 @@ static int virt_kvm_type(MachineState *ms, const char *type_str) VirtMachineState *vms = VIRT_MACHINE(ms); int rme_vm_type = kvm_arm_rme_vm_type(ms); int max_vm_pa_size, requested_pa_size; + int rme_reserve_bit = 0; bool fixed_ipa; - max_vm_pa_size = kvm_arm_get_max_vm_ipa_size(ms, &fixed_ipa); + if (rme_vm_type) { + /* + * With RME, the upper GPA bit differentiates Realm from NS memory. + * Reserve the upper bit to ensure that highmem devices will fit. + */ + rme_reserve_bit = 1; + } + + max_vm_pa_size = kvm_arm_get_max_vm_ipa_size(ms, &fixed_ipa) - + rme_reserve_bit; /* we freeze the memory map to compute the highest gpa */ virt_set_memmap(vms, max_vm_pa_size); - requested_pa_size = 64 - clz64(vms->highest_gpa); + requested_pa_size = 64 - clz64(vms->highest_gpa) + rme_reserve_bit; /* * KVM requires the IPA size to be at least 32 bits. From patchwork Mon Nov 25 19:56:17 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Philippe Brucker X-Patchwork-Id: 13885240 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 1DAA1D59D67 for ; Mon, 25 Nov 2024 20:06:06 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tFfFP-0005Ip-0G; Mon, 25 Nov 2024 14:59:51 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tFfFH-0005AZ-Hk for qemu-devel@nongnu.org; Mon, 25 Nov 2024 14:59:43 -0500 Received: from mail-wr1-x42d.google.com ([2a00:1450:4864:20::42d]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1tFfFA-0004qe-6j for qemu-devel@nongnu.org; Mon, 25 Nov 2024 14:59:43 -0500 Received: by mail-wr1-x42d.google.com with SMTP id ffacd0b85a97d-3822ba3cdbcso3014201f8f.0 for ; Mon, 25 Nov 2024 11:59:35 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1732564775; x=1733169575; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=a59XHnG8h+nIeFzh80GUuHguY0Zka09dW1/TbkEKxDk=; b=pprp2SViVYifoJn3Kcq5KOfLqCasJhpKzWWwaH7WDQpsWMIOpIwKPI7fc9JlRBFHa2 rcwCjfFPICqZ9gbPMx6kg2tMVoCEA9dx+/KR8gel8h35UIuDJqppeRKLUu5FSOZwjrnv e9iloj+43He6qmjh5qpGvhY4cZ1HYwvVzwIOVT4tO/GG5NlEW1Alet8Lar/PNGqZ7sCN UOhXVQeUUWljQxhqIipMjy/UU7BkY7Eqm7+ULkPrH+27kQdNnUG8autZtH7DGiXQV+09 0k6ydZbvnaFWVJNvX4LXrTW+tAnGbmBKmr8hA4n7zqzRoL9Fa7ny8fcNuwNuiBbBTILw FrSg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1732564775; x=1733169575; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=a59XHnG8h+nIeFzh80GUuHguY0Zka09dW1/TbkEKxDk=; b=wZ+MWl+1IWOLhtDGxk64vn1ouCNxZmMB47DFyTSzjffduatRUJN98z8ie9GyIFj4x0 0t+lwb74ajdl5GU545vRM9/tLh/iVylB9Sc++qT7rjxsOq6k0bEQeWkTYmul31GKT0vw c3gZ1RZND/JnqPpHaPmAFTN7crSP7EZC3LB/JwkwQFaiz/xgwi+WM5yaowMUfTVZ6Fbr eeWlfSctjQW8J5eWt3IFu/G0b9s7vd4gWiBlOpWlQWw8BGFHF+Zps7ivXYa5TjoKEhcn cAs5gBPKwCZLRZWLCdBS8CySndFhby+XUDxE2acvY5TAnR4jmD2ZjDT8qGNb5l5xjdgv DYCw== X-Forwarded-Encrypted: i=1; AJvYcCXV4ViuKeAAbEgRYXVrCxc0/5KjUItyit2G3uoGjSWARNUvWQmONZiX77JFC7eMSRCaCrbUSzGEmLtl@nongnu.org X-Gm-Message-State: AOJu0YxoWk2I+8ZuVb11BPGOMBVpLvoHdfegAm5nJs4kB4HY4SFchbU0 hMtq08HHghAopW8VgMZuQKOioQ3zkzA7JQ79BaAbCbrK01+fLrhUYt7vubKoJR8= X-Gm-Gg: ASbGnctunQArlFsDe1kJdmvHr0cfz1txsVJZKWHH1MdvSDrArCu9fUa/MQP8czsAamS nPIxKBSJd1Ta8ZzARMs6IFI5roRwDJob6wG+aUaCLLTBGhkS98Lky3Z2rA+rMmzVmExPV6XM92b Z+cTPRKBD7hfJHQa6OxzJQIc/M084kcDDck6W9iuKUeHneB3A2XPk8IO89HFCkth4Tux5JFdCwA ugbvWKJnXQFFss9FM7pXDYY9HIQ99+JETce+hm10TVQShs8GXBnTVgD4fcuE/vob4IY X-Google-Smtp-Source: AGHT+IHw3piCsY1SYgCrnqKdV96wffE5D/aAxPSvz1IACBcKd/oVvMDVzCGHC+uO8C/BpUQCIXl+JQ== X-Received: by 2002:a05:6000:184d:b0:382:4b5c:419d with SMTP id ffacd0b85a97d-38260b878e1mr11702601f8f.28.1732564774795; Mon, 25 Nov 2024 11:59:34 -0800 (PST) Received: from localhost.localdomain ([2.221.137.100]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3825fd0fbdcsm11237971f8f.109.2024.11.25.11.59.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 25 Nov 2024 11:59:34 -0800 (PST) From: Jean-Philippe Brucker To: peter.maydell@linaro.org Cc: richard.henderson@linaro.org, philmd@linaro.org, qemu-arm@nongnu.org, qemu-devel@nongnu.org, alex.bennee@linaro.org, Jean-Philippe Brucker Subject: [PATCH v3 18/26] hw/arm/boot: Mark all guest memory as RIPAS_RAM. Date: Mon, 25 Nov 2024 19:56:17 +0000 Message-ID: <20241125195626.856992-20-jean-philippe@linaro.org> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241125195626.856992-2-jean-philippe@linaro.org> References: <20241125195626.856992-2-jean-philippe@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::42d; envelope-from=jean-philippe@linaro.org; helo=mail-wr1-x42d.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org All Realm IPA states are by default RIPAS_EMPTY, and accessing them in that state causes injection of synchronous exception. Either the loader or the guest needs to set IPA state to RIPAS_RAM before accessing it. Since a Linux guest needs all memory ready at boot [1], initialize it here. [1] https://docs.kernel.org/arch/arm64/booting.html https://lore.kernel.org/all/20241004144307.66199-12-steven.price@arm.com/ Signed-off-by: Jean-Philippe Brucker --- v2->v3: New: the Linux guest does not initialize RIPAS itself anymore, and expects the loader to do it. --- hw/arm/boot.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/hw/arm/boot.c b/hw/arm/boot.c index 5301d8d318..a2414b1f98 100644 --- a/hw/arm/boot.c +++ b/hw/arm/boot.c @@ -26,6 +26,7 @@ #include "qemu/config-file.h" #include "qemu/option.h" #include "qemu/units.h" +#include "kvm_arm.h" /* Kernel boot protocol is specified in the kernel docs * Documentation/arm/Booting and Documentation/arm64/booting.txt @@ -1238,6 +1239,9 @@ void arm_load_kernel(ARMCPU *cpu, MachineState *ms, struct arm_boot_info *info) info->dtb_filename = ms->dtb; info->dtb_limit = 0; + /* Mark all Realm memory as RAM */ + kvm_arm_rme_init_guest_ram(info->loader_start, info->ram_size); + /* Load the kernel. */ if (!info->kernel_filename || info->firmware_loaded) { arm_setup_firmware_boot(cpu, info); From patchwork Mon Nov 25 19:56:18 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Philippe Brucker X-Patchwork-Id: 13885233 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 7AC60D59D67 for ; Mon, 25 Nov 2024 20:04:41 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tFfFQ-0005NH-3P; Mon, 25 Nov 2024 14:59:52 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tFfFH-0005Ab-Iz for qemu-devel@nongnu.org; Mon, 25 Nov 2024 14:59:43 -0500 Received: from mail-wr1-x431.google.com ([2a00:1450:4864:20::431]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1tFfFA-0004qv-SE for qemu-devel@nongnu.org; Mon, 25 Nov 2024 14:59:43 -0500 Received: by mail-wr1-x431.google.com with SMTP id ffacd0b85a97d-3824446d2bcso4300996f8f.2 for ; Mon, 25 Nov 2024 11:59:36 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1732564775; x=1733169575; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=DywAE1h0x8RJnjNb6ZyyKOUQTV8+QaXBhNrpy+I4lm8=; b=MuE9dgHEm5E3cWeO0m6XMqf+KqbUiGtMZMzxlQC/sVjcuQ1yNWkATGtqHgN+4alyr/ hGRZCOzS17yR/dJzeHsCiCoMp9VObClkT821EIrpVPpa06LyzylG1FI+MwbebG9ldsix HmQ3wNggxZt35C8jJf+zCM1Pcovvz3u1/LPEmneNKPOzkhwvi3F7MgoftwdwD5ICJPxm R9IUUxmQAmoiFSEVryNxJqEZ9HURud4AR5valJcAu0TLI9Sh40tb/0ZVsISPwVbsuAyL 49wpJCJTAQCYrTkzlBTIBppptRZdWpQblOEstNkzZRS8nSdR7k9Jyw7lO9RV6FYr+jy8 tKgQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1732564775; x=1733169575; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=DywAE1h0x8RJnjNb6ZyyKOUQTV8+QaXBhNrpy+I4lm8=; b=FuaI6WflAXUjf9Rhv9CN13GRRg3kAoJa5+LOGlELlF/RaK7KJ4BhcqChtTsjewfYmD oNeQDaZKMx2c5axHhMauFO2LyC1A5RBdF+lcSrTblyLWIRN5z8D6c+N4X+rhU/B4Waux Hd503gqHmJOGR9TxA/TlZS/HusmwEkyt6KMWHMh/7PIVnYZbKU2vMSTi9Y7HLk8V22gS kuKiMK0aWp9Z85fL/VEPMfo+87FqdQA+SXUG1PO/pU/KPnyQW422rrgCuhEtu7OsTGjF cE/0RpatuOet/QOk8uINeBHNbZhuqlLdoaGXbohaGhx+aRpNM1btv25pEaAacuLijWou xaPg== X-Forwarded-Encrypted: i=1; AJvYcCWj7tXVNawtuAb7NHWWUbpTUJz14QEJjaKCEX5PdFUoOLy8DoeNUyHHYHllgS15i51pZbNI5mvZGag9@nongnu.org X-Gm-Message-State: AOJu0YwXUnJjcSl/IOhTjZWe0asN8gR5/swBmOWy0tpjDwfWL5BJn/S7 Fy7KyIMbuO8pdXbbgVxbCkzGVZbcBtr3QJ7vJlZJ0ZX7UQ4bCSCkOdDbAb3eXMM= X-Gm-Gg: ASbGnctzS6hkZJAYlTo45qcb2RJtjjMiHoQLTiB837YSjtyr1hkiqGpM8VPxUM5o4ck 37Agkrz4fDKLJSHO/6KsIL8rTAqwvBmUUYN9FkfPAO3Q+Az4P4vq1xmn6U21LMVNYGRQXHnrKrk UttI0rnyZavFeyw6Yi5yREiX2qpFxJ3+8+KwtsARIl7f6GscmqKSIv2hI+Utw9x7OXymsnYio73 VGPFWNyIFspptbJBjDJktDHhWknF84XrG8/j5mlo/l2YzaGzUaMwqEw66Fm2NFmVcfW X-Google-Smtp-Source: AGHT+IFcITnBM6NuekDsP94qupu4u1K65i9I9qgzFbjGkHe4n3FTfQzWMtxpGxczoDQxw6ewpdqeIQ== X-Received: by 2002:a05:6000:1788:b0:382:51d7:a2e0 with SMTP id ffacd0b85a97d-38260b61f45mr13353893f8f.27.1732564775393; Mon, 25 Nov 2024 11:59:35 -0800 (PST) Received: from localhost.localdomain ([2.221.137.100]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3825fd0fbdcsm11237971f8f.109.2024.11.25.11.59.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 25 Nov 2024 11:59:35 -0800 (PST) From: Jean-Philippe Brucker To: peter.maydell@linaro.org Cc: richard.henderson@linaro.org, philmd@linaro.org, qemu-arm@nongnu.org, qemu-devel@nongnu.org, alex.bennee@linaro.org, Jean-Philippe Brucker Subject: [PATCH v3 19/26] hw/arm/virt: Move virt_flash_create() to machvirt_init() Date: Mon, 25 Nov 2024 19:56:18 +0000 Message-ID: <20241125195626.856992-21-jean-philippe@linaro.org> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241125195626.856992-2-jean-philippe@linaro.org> References: <20241125195626.856992-2-jean-philippe@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::431; envelope-from=jean-philippe@linaro.org; helo=mail-wr1-x431.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org For confidential VMs we'll want to skip flash device creation. Unfortunately, in virt_instance_init() the machine->cgs member has not yet been initialized, so we cannot check whether confidential guest is enabled. Move virt_flash_create() to machvirt_init(), where we can access the machine->cgs member. Signed-off-by: Jean-Philippe Brucker --- hw/arm/virt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/arm/virt.c b/hw/arm/virt.c index eb94997914..c4cf69ea33 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -2124,6 +2124,8 @@ static void machvirt_init(MachineState *machine) unsigned int smp_cpus = machine->smp.cpus; unsigned int max_cpus = machine->smp.max_cpus; + virt_flash_create(vms); + possible_cpus = mc->possible_cpu_arch_ids(machine); /* @@ -3359,8 +3361,6 @@ static void virt_instance_init(Object *obj) vms->irqmap = a15irqmap; - virt_flash_create(vms); - vms->oem_id = g_strndup(ACPI_BUILD_APPNAME6, 6); vms->oem_table_id = g_strndup(ACPI_BUILD_APPNAME8, 8); } From patchwork Mon Nov 25 19:56:19 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Philippe Brucker X-Patchwork-Id: 13885229 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id DB6DDD59D67 for ; Mon, 25 Nov 2024 20:03:49 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tFfFT-0005UD-K7; Mon, 25 Nov 2024 14:59:55 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tFfFL-0005Fl-Gp for qemu-devel@nongnu.org; Mon, 25 Nov 2024 14:59:47 -0500 Received: from mail-wm1-x32a.google.com ([2a00:1450:4864:20::32a]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1tFfFB-0004rC-GO for qemu-devel@nongnu.org; Mon, 25 Nov 2024 14:59:47 -0500 Received: by mail-wm1-x32a.google.com with SMTP id 5b1f17b1804b1-434a2033562so6799455e9.1 for ; Mon, 25 Nov 2024 11:59:37 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1732564776; x=1733169576; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=/1bXq+74SiZeUGfQFbFaJNCrHb1OmghaBQp3KgUN++M=; b=dKeMCTX54+W7PJHxGuXJ+vxE8Jd/SmgrPHiwnmgUZRBV31WEa9//sWVTQppiTTEC+H zs6Tm2x2V2L2Xdmxza6XH1voeNdVy4Im7ntaLaEH+bJTqB7BO9tvO8dshbONPWBUJf+w HSnWtZlET6usH7HlnvQNGpr/44Me2qw3/Rq+wAQjK/2Md8pF+ZHhAXgtAirCNBETirA4 VXw1MmYLYGqVjZsFhHDM0UzcjTCBhcJmC6I/15/M3qyxsH27fl25QOgm0xiL2zCPFf9C f4XtiV/T9l7ubL8GHT28WzYbDOHeZNJlK7LXuILRsTeyzfCejo+AayvF/DHwMWYNLp18 GN4A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1732564776; x=1733169576; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=/1bXq+74SiZeUGfQFbFaJNCrHb1OmghaBQp3KgUN++M=; b=IEztW1gdrxiI8MSyzBXHFlkCYAtiYfnn46qyiV9l43m+RvwOxg7WXWyh5SojlFAKBo 5jioUrRwzDT2w0SyX9c1S7tj5FqBlGRjdg82uTm828fmV40SjpF6NMMh2E3c4HReT625 oDnvWi9AcfFwbTa9SAuaCdFp7WOVK63YlN4MlusrO0QQsAcUfyIqJInVpw2YvAlyUKd0 Xbyxxfj8bBCTv1R4u2BlFIblLm9DJlpkVLneLOim7ffiLfNO5bmCK/COctXqwRD/a+eR 2xQoPJH5CpI6Z8sAurZDCDrsMwNLXYgCauaiUF/7ppH8AgxaiONTLZh8lHgSDNadsltb NzmA== X-Forwarded-Encrypted: i=1; AJvYcCVMOJmU8PejbS5MhpUZYg+l1tJ9kqD9IHdCf1xmnZxuthm3Ib/JRcDiAsmaVnWorrwuLXAlS9pNLWyo@nongnu.org X-Gm-Message-State: AOJu0YyuINdhGwCfEEhCR9yMtmZt9KcVDI1eOhOh6nsP2IFFzDXZfTrv WVD55O0qSj7cbg6DqqnqJB+ThCey188TuALXYIcD3JvOzVT18aSlEehwUUYTpYU= X-Gm-Gg: ASbGncu39ICNUGk/WAq5qJo2jiQbRDz2DmjwNSgZyCDxuE2WtUSUdl7nZvS5neSqlOn GbjEdrWrUw5mG3cFzQt6scmfVKPSLHdUNMiVbXI6WEv708cxxXWF7uHm5wf8P3vzltlqCS+Pph+ 9C9GDPJDG1tzE5s3cbjvqGKqvZiBj0cYGh20crJcszNiIzKSxtdMD/RKDpraBtKQ6CNXTSXRhtn JAsmW8rfyxdr5qQfCK0o28z+YpwW5IXF0Ds1sWdQ4LO+syKgAlDw8/bIh33pJBEcCGt X-Google-Smtp-Source: AGHT+IFQgR9S9GvWuMKUvIDpUn9BlZAf2a1+Fz9wP/Nv1NRFaz6POwZPlcO/sIKSbai/bFFqVIoa7g== X-Received: by 2002:a05:6000:4026:b0:382:3400:1ee9 with SMTP id ffacd0b85a97d-38260b5d6c1mr13383314f8f.14.1732564775976; Mon, 25 Nov 2024 11:59:35 -0800 (PST) Received: from localhost.localdomain ([2.221.137.100]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3825fd0fbdcsm11237971f8f.109.2024.11.25.11.59.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 25 Nov 2024 11:59:35 -0800 (PST) From: Jean-Philippe Brucker To: peter.maydell@linaro.org Cc: richard.henderson@linaro.org, philmd@linaro.org, qemu-arm@nongnu.org, qemu-devel@nongnu.org, alex.bennee@linaro.org, Jean-Philippe Brucker Subject: [PATCH v3 20/26] hw/arm/virt: Use RAM instead of flash for confidential guest firmware Date: Mon, 25 Nov 2024 19:56:19 +0000 Message-ID: <20241125195626.856992-22-jean-philippe@linaro.org> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241125195626.856992-2-jean-philippe@linaro.org> References: <20241125195626.856992-2-jean-philippe@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::32a; envelope-from=jean-philippe@linaro.org; helo=mail-wm1-x32a.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org The flash device that holds firmware code relies on read-only stage-2 mappings. Read accesses behave as RAM and write accesses as MMIO. Since the RMM does not support read-only mappings we cannot use the flash device as-is. That isn't a problem because the firmware does not want to disclose any information to the host, hence will not store its variables in clear persistent memory. We can therefore replace the flash device with RAM, and load the firmware there. Signed-off-by: Jean-Philippe Brucker --- include/hw/arm/boot.h | 9 +++++++++ hw/arm/boot.c | 32 ++++++++++++++++++++++++++++-- hw/arm/virt.c | 45 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 84 insertions(+), 2 deletions(-) diff --git a/include/hw/arm/boot.h b/include/hw/arm/boot.h index 80c492d742..d91cfc6942 100644 --- a/include/hw/arm/boot.h +++ b/include/hw/arm/boot.h @@ -112,6 +112,10 @@ struct arm_boot_info { */ bool firmware_loaded; + /* Used when loading firmware into RAM */ + hwaddr firmware_base; + hwaddr firmware_max_size; + /* Address at which board specific loader/setup code exists. If enabled, * this code-blob will run before anything else. It must return to the * caller via the link register. There is no stack set up. Enabled by @@ -132,6 +136,11 @@ struct arm_boot_info { bool secure_board_setup; arm_endianness endianness; + + /* + * Confidential guest boot loads everything into RAM so it can be measured. + */ + bool confidential; }; /** diff --git a/hw/arm/boot.c b/hw/arm/boot.c index a2414b1f98..4cf7dd5b4d 100644 --- a/hw/arm/boot.c +++ b/hw/arm/boot.c @@ -1150,7 +1150,31 @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu, } } -static void arm_setup_firmware_boot(ARMCPU *cpu, struct arm_boot_info *info) +static void arm_setup_confidential_firmware_boot(ARMCPU *cpu, + struct arm_boot_info *info, + const char *firmware_filename) +{ + ssize_t fw_size; + const char *fname; + AddressSpace *as = arm_boot_address_space(cpu, info); + + fname = qemu_find_file(QEMU_FILE_TYPE_BIOS, firmware_filename); + if (!fname) { + error_report("Could not find firmware image '%s'", firmware_filename); + exit(1); + } + + fw_size = load_image_targphys_as(firmware_filename, + info->firmware_base, + info->firmware_max_size, as); + if (fw_size <= 0) { + error_report("could not load firmware '%s'", firmware_filename); + exit(1); + } +} + +static void arm_setup_firmware_boot(ARMCPU *cpu, struct arm_boot_info *info, + const char *firmware_filename) { /* Set up for booting firmware (which might load a kernel via fw_cfg) */ @@ -1201,6 +1225,10 @@ static void arm_setup_firmware_boot(ARMCPU *cpu, struct arm_boot_info *info) } } + if (info->confidential) { + arm_setup_confidential_firmware_boot(cpu, info, firmware_filename); + } + /* * We will start from address 0 (typically a boot ROM image) in the * same way as hardware. Leave env->boot_info NULL, so that @@ -1244,7 +1272,7 @@ void arm_load_kernel(ARMCPU *cpu, MachineState *ms, struct arm_boot_info *info) /* Load the kernel. */ if (!info->kernel_filename || info->firmware_loaded) { - arm_setup_firmware_boot(cpu, info); + arm_setup_firmware_boot(cpu, info, ms->firmware); } else { arm_setup_direct_kernel_boot(cpu, info); } diff --git a/hw/arm/virt.c b/hw/arm/virt.c index c4cf69ea33..0750c83fae 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -1228,6 +1228,10 @@ static PFlashCFI01 *virt_flash_create1(VirtMachineState *vms, static void virt_flash_create(VirtMachineState *vms) { + if (virt_machine_is_confidential(vms)) { + return; + } + vms->flash[0] = virt_flash_create1(vms, "virt.flash0", "pflash0"); vms->flash[1] = virt_flash_create1(vms, "virt.flash1", "pflash1"); } @@ -1263,6 +1267,10 @@ static void virt_flash_map(VirtMachineState *vms, hwaddr flashsize = vms->memmap[VIRT_FLASH].size / 2; hwaddr flashbase = vms->memmap[VIRT_FLASH].base; + if (virt_machine_is_confidential(vms)) { + return; + } + virt_flash_map1(vms->flash[0], flashbase, flashsize, secure_sysmem); virt_flash_map1(vms->flash[1], flashbase + flashsize, flashsize, @@ -1278,6 +1286,10 @@ static void virt_flash_fdt(VirtMachineState *vms, MachineState *ms = MACHINE(vms); char *nodename; + if (virt_machine_is_confidential(vms)) { + return; + } + if (sysmem == secure_sysmem) { /* Report both flash devices as a single node in the DT */ nodename = g_strdup_printf("/flash@%" PRIx64, flashbase); @@ -1313,6 +1325,27 @@ static void virt_flash_fdt(VirtMachineState *vms, } } +static bool virt_confidential_firmware_init(VirtMachineState *vms, + MemoryRegion *sysmem) +{ + MemoryRegion *fw_ram; + hwaddr fw_base = vms->memmap[VIRT_FLASH].base; + hwaddr fw_size = vms->memmap[VIRT_FLASH].size; + + if (!MACHINE(vms)->firmware) { + return false; + } + + assert(machine_require_guest_memfd(MACHINE(vms))); + + fw_ram = g_new(MemoryRegion, 1); + memory_region_init_ram_guest_memfd(fw_ram, NULL, "fw_ram", fw_size, + &error_fatal); + memory_region_add_subregion(sysmem, fw_base, fw_ram); + + return true; +} + static bool virt_firmware_init(VirtMachineState *vms, MemoryRegion *sysmem, MemoryRegion *secure_sysmem) @@ -1321,6 +1354,15 @@ static bool virt_firmware_init(VirtMachineState *vms, const char *bios_name; BlockBackend *pflash_blk0; + /* + * For a confidential VM, the firmware image and any boot information, + * including EFI variables, are stored in RAM in order to be measurable and + * private. Create a RAM region and load the firmware image there. + */ + if (virt_machine_is_confidential(vms)) { + return virt_confidential_firmware_init(vms, sysmem); + } + /* Map legacy -drive if=pflash to machine properties */ for (i = 0; i < ARRAY_SIZE(vms->flash); i++) { pflash_cfi01_legacy_drive(vms->flash[i], @@ -2463,7 +2505,10 @@ static void machvirt_init(MachineState *machine) vms->bootinfo.get_dtb = machvirt_dtb; vms->bootinfo.skip_dtb_autoload = true; vms->bootinfo.firmware_loaded = firmware_loaded; + vms->bootinfo.firmware_base = vms->memmap[VIRT_FLASH].base; + vms->bootinfo.firmware_max_size = vms->memmap[VIRT_FLASH].size; vms->bootinfo.psci_conduit = vms->psci_conduit; + vms->bootinfo.confidential = virt_machine_is_confidential(vms); arm_load_kernel(ARM_CPU(first_cpu), machine, &vms->bootinfo); vms->machine_done.notify = virt_machine_done; From patchwork Mon Nov 25 19:56:20 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Philippe Brucker X-Patchwork-Id: 13885232 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 0BA26D59D69 for ; Mon, 25 Nov 2024 20:04:31 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tFfFM-0005GN-Qa; Mon, 25 Nov 2024 14:59:48 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tFfFI-0005Bf-Q0 for qemu-devel@nongnu.org; Mon, 25 Nov 2024 14:59:44 -0500 Received: from mail-wr1-x42c.google.com ([2a00:1450:4864:20::42c]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1tFfFC-0004rZ-1D for qemu-devel@nongnu.org; Mon, 25 Nov 2024 14:59:44 -0500 Received: by mail-wr1-x42c.google.com with SMTP id ffacd0b85a97d-38231e9d518so3171520f8f.0 for ; Mon, 25 Nov 2024 11:59:37 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1732564776; x=1733169576; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=EExZMgepRcWmxIXjjA6QAMdeM+PVS7qSljKvbhpCK2g=; b=RmTDz9imuVe5UtgC8SIeKmKaxnKorqRey1D5rliAOoh8zRYuChE7VkDhnwr2PCBBD+ P0UlaCEYFPv8JdcgGGM6EDqaMTCIH9vbTyC/LZwDGYSQ4CYoJKPAR/ZfvPhMTtrmPHiK kbGy1uyu5iP5YGIG//5wjv1/yiKVKuHBBMr3/4RKue0jj0d3mVGGeY0FGyxsIexK9TzW Ru/cd/fj37JSMAS3T4Z7FljGGvz8Draxgc7Ae8O+qIqOEBfEm2eSVjgV0S5DZ/HDjywE 1U4GI2PPjtBhjrDwu3oa44yFo5WB9Gtamvhqs+1ufeyGEDvhHLcSNJDe7IOs5ubnuacD PPGA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1732564776; x=1733169576; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=EExZMgepRcWmxIXjjA6QAMdeM+PVS7qSljKvbhpCK2g=; b=jEbUFbORlkqs90B21GQyBQuB5FfBQyyDwSxIAoz8RJITrCe51h5ekjNQDYGnwApwW2 mBmycCioa1oKAZ4hkzvOp59OQmA712HudgCmVU6IT6S06STeKBf6URyI+SbOZQpk/P84 dRGtmSEl7GB0I3tYtjfaiiiDU0gYppNL+DEQK4LVFoCg+yOzpG4XUT0hRpPDCCLx3nKk SLL8++P/Pu/lafPaOvJQ9j6kgEzh6R2JX6rZ1Y8nZq3mDKVU1xjMkH82MzT/MB4WqMkV ohelvZYkqcox1yF5okAItwW9M54cA1X9BVAiWHsUkjnd2RBxNuVEjDoahXuFUYWx88Wh UzOQ== X-Forwarded-Encrypted: i=1; AJvYcCXJuIETjkotUaJgFrdqPAjRXC8UBPpcGDOMOKBbUhoJiT64OiVjjt5AwGnXK49Rsp0AmGI9Gg9wJIKx@nongnu.org X-Gm-Message-State: AOJu0YxcZBDnjWQRWbBHAfEkgvQEgNPBz6UOwwZkXzbkSanyjQfXbROY zigWe8j8vjS6edhulK8UKvpuDsGHs8Ll6t2DJgArJUChCY88qN+vJrCfkomDcXk= X-Gm-Gg: ASbGncvBwPBQ4Rf6Vtd6d1k59SWKW4gyUi0XnmdqnCj/WxU+iBFQTuM+FzUsptTKkjY igO+I91tp7LH7vXbSyxPyViUCW+7Lm41HFdf8s6LCB7Cy5/x1Y4OYL1+rKNy57Aw7BG2hDabEYo 5OLERDRFMZOmo/g2NbxGwmhXkEx9jCKaSprpPLsxvYVJxk2++BkTsg3TG+3UTrDdm4Oa30YrqpO 3/btftVDWeiQ/Hf0x5v9q2MCzXjufM0TpQNSqRVslIQmIE4x7GwGWnwA2S/4CdbLoN5 X-Google-Smtp-Source: AGHT+IEpRKX4vqQ5F4ReAVoyjQEr4k+dgtHCLaUTopY3J7lBIhLeQk4UiEwxtDtCCt9+elRt/DkjZA== X-Received: by 2002:a5d:6dad:0:b0:381:b68f:d14b with SMTP id ffacd0b85a97d-38260bc860dmr13424465f8f.45.1732564776596; Mon, 25 Nov 2024 11:59:36 -0800 (PST) Received: from localhost.localdomain ([2.221.137.100]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3825fd0fbdcsm11237971f8f.109.2024.11.25.11.59.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 25 Nov 2024 11:59:36 -0800 (PST) From: Jean-Philippe Brucker To: peter.maydell@linaro.org Cc: richard.henderson@linaro.org, philmd@linaro.org, qemu-arm@nongnu.org, qemu-devel@nongnu.org, alex.bennee@linaro.org, Jean-Philippe Brucker Subject: [RFC PATCH v3 21/26] hw/arm/boot: Load DTB as is for confidential VMs Date: Mon, 25 Nov 2024 19:56:20 +0000 Message-ID: <20241125195626.856992-23-jean-philippe@linaro.org> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241125195626.856992-2-jean-philippe@linaro.org> References: <20241125195626.856992-2-jean-philippe@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::42c; envelope-from=jean-philippe@linaro.org; helo=mail-wr1-x42c.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org For confidential VMs it may be necessary to measure the DTB, to ensure a malicious host does not insert harmful information in there. In case an external tool can generated and measured the DTB, load it as is without patching it. Signed-off-by: Jean-Philippe Brucker --- v2->v3: new --- hw/arm/boot.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/hw/arm/boot.c b/hw/arm/boot.c index 4cf7dd5b4d..20b3071339 100644 --- a/hw/arm/boot.c +++ b/hw/arm/boot.c @@ -523,7 +523,14 @@ int arm_load_dtb(hwaddr addr, const struct arm_boot_info *binfo, char **node_path; Error *err = NULL; - if (binfo->dtb_filename) { + if (binfo->dtb_filename && binfo->confidential) { + /* + * If the user is providing a DTB for a confidential VM, it is already + * tailored to this configuration and measured. Load it as is, without + * any modification. + */ + return rom_add_file_fixed_as(binfo->dtb_filename, addr, -1, as); + } else if (binfo->dtb_filename) { char *filename; filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, binfo->dtb_filename); if (!filename) { From patchwork Mon Nov 25 19:56:21 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Philippe Brucker X-Patchwork-Id: 13885220 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 65917D59D68 for ; Mon, 25 Nov 2024 20:01:30 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tFfFO-0005I3-BM; Mon, 25 Nov 2024 14:59:50 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tFfFK-0005Em-Hc for qemu-devel@nongnu.org; Mon, 25 Nov 2024 14:59:46 -0500 Received: from mail-wm1-x32d.google.com ([2a00:1450:4864:20::32d]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1tFfFC-0004ru-TJ for qemu-devel@nongnu.org; Mon, 25 Nov 2024 14:59:45 -0500 Received: by mail-wm1-x32d.google.com with SMTP id 5b1f17b1804b1-43167ff0f91so44393155e9.1 for ; Mon, 25 Nov 2024 11:59:38 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1732564777; x=1733169577; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=0X0EuUhZkl3V6dkF5yC+rBGIPkT3Qq6H9A8p4Nm7TQw=; b=hpz6CoXWrfu/u5D/zuUdjHh/AvL8kP27mzNPXiXdNnoalsfkyzsBrzGSqBII1X7CIa rp17wBbh7KHPR2xV2TNhp7/ta9AogEokpZjqOH5OiRBnC6mqK7P1w5EmEeyu3vF1ZrJv Rqrf6NRdA2YmWzedbX6P3Om39hocVrlgGKlgnj02Oslb/sJxeb4iISvhq91Df+axqSuz x7PpQbz3GsEDERvckGsNDWJTfsz7ZfcyULuDI3fqQhdQX2xadmLZYUfcK4Rvl0vfR+Kw hroJBsgXpx/9M8TR8JBj6TvaZA301YtxUj6ZNOiMyzyprwnIqoQbnlpJTGVdGHK5/Pym IAOw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1732564777; x=1733169577; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=0X0EuUhZkl3V6dkF5yC+rBGIPkT3Qq6H9A8p4Nm7TQw=; b=EXaDtip1lRuSytzP6s3rJFwTUIJWz0+6R+aHT4Nogsi3ZpkKhS4/nhXNQzZ5lFxNlU uBCOjC9SjnZw/G1oCpnKPNTnl7MD+BVm4CGAUseuEvSzfLZxCYJVSAo24PDky/dNDAse wRN9UvEDABqlrTlNzL6xMIoM7yyA9S1QOUTCN+wmrwN/hlGRsOgpnDieILTusktlCIrj OXe2xP1AJ2ElQeSB6Z9LHybfYLVQ44SyIWeK1bZPrDQv2+3ZMhGVVyL/UHFhkWGKJR6R pIyJcwoPUyuqcw2Qz0GyqQO/jtPN6kVuL18HkZuL6NBypstdyQ6Jm+cz3udhiqpFC+ei +RjA== X-Forwarded-Encrypted: i=1; AJvYcCWcXAetnsNvuVxjjgshZV+2EFUzg7fV8dZHws/xbWCsRAp5idw0uLtS16M2GcFR2P1xSnqf6lI8+i8g@nongnu.org X-Gm-Message-State: AOJu0Yxvyt7xB8HIWk2d9S2yRilHHUNQr29GaxDusMf9JWF58zzhukAp QvoEayi+zuNjdPU23oDPQdzPyyinnTcYbV5hBbmBXcBXAT1WmrOLSj3D0QYJyY8= X-Gm-Gg: ASbGncvXdYCk8R0r1qSjZcTRZeLcWCaghjpWHm1Lo/mOQpeKoVU6xi1sX6xYOIQ4rnz Fh8b+MQ+rOLnSv0qi/+/bW7qqwP0QiptD5gzDGCOjc9FcuKRItBPF0U9pGFhjGwFGg6Uk98d+8I Mp3yd1+jdZDnIMmPKcnZ7y4C+eo0kgxZUUFy4Hpdi3sDWDe2MyVtbOjUjXsK9/4Pdxe1aXjbkHJ aESqR0HMjTfC3znSE0jRbLBlrVmtxyAmln0LcovKAWcbPa/u4qV95du9hhdoS3NjtKn X-Google-Smtp-Source: AGHT+IFSmpP21tnbsCvXgk64PcQ1IqbTren1CzqreRLS7x4zvWdbhUeeP02hsbF6jzpxXIfyBKQGpQ== X-Received: by 2002:a5d:6d0b:0:b0:385:bd85:5a32 with SMTP id ffacd0b85a97d-385bd855a91mr2115120f8f.15.1732564777217; Mon, 25 Nov 2024 11:59:37 -0800 (PST) Received: from localhost.localdomain ([2.221.137.100]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3825fd0fbdcsm11237971f8f.109.2024.11.25.11.59.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 25 Nov 2024 11:59:36 -0800 (PST) From: Jean-Philippe Brucker To: peter.maydell@linaro.org Cc: richard.henderson@linaro.org, philmd@linaro.org, qemu-arm@nongnu.org, qemu-devel@nongnu.org, alex.bennee@linaro.org, Jean-Philippe Brucker Subject: [RFC PATCH v3 22/26] hw/arm/boot: Skip bootloader for confidential guests Date: Mon, 25 Nov 2024 19:56:21 +0000 Message-ID: <20241125195626.856992-24-jean-philippe@linaro.org> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241125195626.856992-2-jean-philippe@linaro.org> References: <20241125195626.856992-2-jean-philippe@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::32d; envelope-from=jean-philippe@linaro.org; helo=mail-wm1-x32d.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org An independent verifier needs to reconstruct the content of guest memory in order to attest that it is running trusted code. To avoid having to reconstruct the bootloader generated by QEMU, skip this step and jump directly to the kernel, with the DTB address in x0 as specified by the Linux boot protocol [1]. [1] https://docs.kernel.org/arch/arm64/booting.html Signed-off-by: Jean-Philippe Brucker --- v2->v3: new --- include/hw/arm/boot.h | 6 ++++++ hw/arm/boot.c | 23 +++++++++++++++++------ hw/arm/virt.c | 1 + 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/include/hw/arm/boot.h b/include/hw/arm/boot.h index d91cfc6942..5fcbaa2625 100644 --- a/include/hw/arm/boot.h +++ b/include/hw/arm/boot.h @@ -137,6 +137,12 @@ struct arm_boot_info { arm_endianness endianness; + /* + * Instead of starting in a small bootloader that jumps to the kernel, + * immediately start in the kernel. + */ + bool skip_bootloader; + /* * Confidential guest boot loads everything into RAM so it can be measured. */ diff --git a/hw/arm/boot.c b/hw/arm/boot.c index 20b3071339..e461137595 100644 --- a/hw/arm/boot.c +++ b/hw/arm/boot.c @@ -762,7 +762,13 @@ static void do_cpu_reset(void *opaque) if (cs == first_cpu) { AddressSpace *as = arm_boot_address_space(cpu, info); - cpu_set_pc(cs, info->loader_start); + if (info->skip_bootloader) { + assert(is_a64(env)); + env->xregs[0] = info->dtb_start; + cpu_set_pc(cs, info->entry); + } else { + cpu_set_pc(cs, info->loader_start); + } if (!have_dtb(info)) { if (old_param) { @@ -860,7 +866,8 @@ static ssize_t arm_load_elf(struct arm_boot_info *info, uint64_t *pentry, } static uint64_t load_aarch64_image(const char *filename, hwaddr mem_base, - hwaddr *entry, AddressSpace *as) + hwaddr *entry, AddressSpace *as, + bool skip_bootloader) { hwaddr kernel_load_offset = KERNEL64_LOAD_ADDR; uint64_t kernel_size = 0; @@ -912,7 +919,8 @@ static uint64_t load_aarch64_image(const char *filename, hwaddr mem_base, * bootloader, we can just load it starting at 2MB+offset rather * than 0MB + offset. */ - if (kernel_load_offset < BOOTLOADER_MAX_SIZE) { + if (kernel_load_offset < BOOTLOADER_MAX_SIZE && + !skip_bootloader) { kernel_load_offset += 2 * MiB; } } @@ -996,7 +1004,8 @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu, } if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64) && kernel_size < 0) { kernel_size = load_aarch64_image(info->kernel_filename, - info->loader_start, &entry, as); + info->loader_start, &entry, as, + info->skip_bootloader); is_linux = 1; if (kernel_size >= 0) { image_low_addr = entry; @@ -1136,8 +1145,10 @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu, fixupcontext[FIXUP_ENTRYPOINT_LO] = entry; fixupcontext[FIXUP_ENTRYPOINT_HI] = entry >> 32; - arm_write_bootloader("bootloader", as, info->loader_start, - primary_loader, fixupcontext); + if (!info->skip_bootloader) { + arm_write_bootloader("bootloader", as, info->loader_start, + primary_loader, fixupcontext); + } if (info->write_board_setup) { info->write_board_setup(cpu, info); diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 0750c83fae..5247f53882 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -2509,6 +2509,7 @@ static void machvirt_init(MachineState *machine) vms->bootinfo.firmware_max_size = vms->memmap[VIRT_FLASH].size; vms->bootinfo.psci_conduit = vms->psci_conduit; vms->bootinfo.confidential = virt_machine_is_confidential(vms); + vms->bootinfo.skip_bootloader = vms->bootinfo.confidential; arm_load_kernel(ARM_CPU(first_cpu), machine, &vms->bootinfo); vms->machine_done.notify = virt_machine_done; From patchwork Mon Nov 25 19:56:22 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jean-Philippe Brucker X-Patchwork-Id: 13885226 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 02908D59D67 for ; Mon, 25 Nov 2024 20:02:28 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tFfFT-0005UR-Kk; Mon, 25 Nov 2024 14:59:55 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tFfFK-0005F6-V6 for qemu-devel@nongnu.org; Mon, 25 Nov 2024 14:59:46 -0500 Received: from mail-wr1-x42f.google.com ([2a00:1450:4864:20::42f]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1tFfFD-0004sP-96 for qemu-devel@nongnu.org; Mon, 25 Nov 2024 14:59:46 -0500 Received: by mail-wr1-x42f.google.com with SMTP id ffacd0b85a97d-3823e45339bso3613061f8f.0 for ; Mon, 25 Nov 2024 11:59:38 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1732564778; x=1733169578; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Gw4CAtCWZHkyS6PsIdGnG26rQiDW6W2BIcqFa8xSXq0=; b=JzQqVVF57x672fr9wxsHVR7LoWZnDKY5EyU7LAjhtCm6buYnNFti2VOsWes97hD3a+ zUVYkVDxJSU/aVxK6ZoOksyBsRG4YMaxyT87SYe8e+SGRcFEavWYy/Nnhu72M4SgM8eh SmLtekDJO0Mr2GCJboMPp9k6PDSRtOgn4m6KgcyFwJ9WITGPOvLitdCOKhcN67tLpZaJ GaH1rH6jEZGJqIXu+g0788KX6KfEZUXkKZ9MuppEeFyuf8JTA5o9Nz9dl8UxS1NwC6cJ Q4Hznu/cMBxPkclH/D5Ze4g1VrDTGLfh36/RDWHxoOXeJadaK9rwXpeKvDMb/ALQIYbj gxzw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1732564778; x=1733169578; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Gw4CAtCWZHkyS6PsIdGnG26rQiDW6W2BIcqFa8xSXq0=; b=vUFdcbYoYb+N4wWc5DJtW9tRqZ7GAQflrtwp3K91b4Y+mYykrFAGJhvjD+yTfp9DSP gfK1AgYWW6mw0y5TsRxKpZriE7s+pv87urc5ne8Dl/vgdMZZFFviHhrVeUVSbgasH6as 7XMFc7K7uS/SVnIGw9+m6WO51l/e07dxHU+GNoa0ibUuRvF6LOc8ethEh4E+IqGxGcrb jdeSiDRUDtSuHpRjU9MZVtlw4GD9+BsoydtIZllxormL0cP+ROVccPd187Kb8AJjxasZ cDlaH6GcP99fk5i3CK7N5E0BEmf/IxO7zNGU0YhsZ1jZdJqO1YsP1JKN0D3Yvj4kDtfG MvfA== X-Forwarded-Encrypted: i=1; AJvYcCWx/YgXviMulRYwmoNJN6LqAuzba4cX9Pn8jQLdWTDF05IAYC2c1wCp/mm6/woXkhlb9lrFBk6jOosp@nongnu.org X-Gm-Message-State: AOJu0Ywzwuor2PgksPhv1d+005ad7jC42WQ3TOPteUNnPGxsY33I0XCD ipJtbRFM6qx7pB/bdYYXmLKTgzuyT7KZub0Yv9NZQ56DDBIDdf1y2xBV0z0rX0U= X-Gm-Gg: ASbGncudii52kMqM63Qhf5AFLj1uKpYGbEO5TqxnInRHM7hHUwlO7KtnyVLiKYtTCOZ DpaZ6BaKJfypiHao8ryJoiwj4QUhsctQK+19U+tAKU4L0uqWhCB/3iThU0V5TxCFBkJ40l/QhOP To5AYZYB0bZvCn0EqvrscAJWokYPSS2G7UEj4Z8aYN1Jpn55P9QJrBt31v3/emlGl32WdPKIq3J NMorV9LhMFBxfCnyaYZexsDMQ2EruE3aAQeQH2mSpegTIQk3DY011HdN8AzhHRRsr6T X-Google-Smtp-Source: AGHT+IEzg8tSZSzM5M7PAnv/+rwiNHPuZQSFt85fVuX8MRm2KzuXcWmnFXwJzhBD8GzVmZB3aeXBDg== X-Received: by 2002:a5d:6dad:0:b0:37d:4e74:684 with SMTP id ffacd0b85a97d-38260be230fmr13303703f8f.52.1732564777822; Mon, 25 Nov 2024 11:59:37 -0800 (PST) Received: from localhost.localdomain ([2.221.137.100]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3825fd0fbdcsm11237971f8f.109.2024.11.25.11.59.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 25 Nov 2024 11:59:37 -0800 (PST) From: Jean-Philippe Brucker To: peter.maydell@linaro.org Cc: richard.henderson@linaro.org, philmd@linaro.org, qemu-arm@nongnu.org, qemu-devel@nongnu.org, alex.bennee@linaro.org, Jean-Philippe Brucker , Stefan Berger Subject: [RFC PATCH v3 23/26] hw/tpm: Add TPM event log Date: Mon, 25 Nov 2024 19:56:22 +0000 Message-ID: <20241125195626.856992-25-jean-philippe@linaro.org> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241125195626.856992-2-jean-philippe@linaro.org> References: <20241125195626.856992-2-jean-philippe@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::42f; envelope-from=jean-philippe@linaro.org; helo=mail-wr1-x42f.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Provide a library allowing the VMM to create an event log that describes what is loaded into memory. During remote attestation in confidential computing this helps an independent verifier reconstruct the initial measurements of a VM, which contain the initial state of memory and CPUs. We provide some definitions and structures described by the Trusted Computing Group (TCG) in "TCG PC Client Platform Firmware Profile Specification" Level 00 Version 1.06 Revision 52 [1]. This is the same format used by UEFI, and UEFI could reuse this log after finding it in DT or ACPI tables, but can also copy its content into a new one. [1] https://trustedcomputinggroup.org/resource/pc-client-specific-platform-firmware-profile-specification/ Cc: Stefan Berger Signed-off-by: Jean-Philippe Brucker --- v2->v3: New --- qapi/tpm.json | 14 ++ include/hw/tpm/tpm_log.h | 89 +++++++++++ hw/tpm/tpm_log.c | 325 +++++++++++++++++++++++++++++++++++++++ hw/tpm/Kconfig | 4 + hw/tpm/meson.build | 1 + 5 files changed, 433 insertions(+) create mode 100644 include/hw/tpm/tpm_log.h create mode 100644 hw/tpm/tpm_log.c diff --git a/qapi/tpm.json b/qapi/tpm.json index a16a72edb9..697e7150ee 100644 --- a/qapi/tpm.json +++ b/qapi/tpm.json @@ -188,3 +188,17 @@ ## { 'command': 'query-tpm', 'returns': ['TPMInfo'], 'if': 'CONFIG_TPM' } + +## +# @TpmLogDigestAlgo: +# +# @sha256: Use the SHA256 algorithm +# +# @sha512: Use the SHA512 algorithm +# +# Algorithm to use for event log digests +# +# Since: 9.3 +## +{ 'enum': 'TpmLogDigestAlgo', + 'data': ['sha256', 'sha512'] } diff --git a/include/hw/tpm/tpm_log.h b/include/hw/tpm/tpm_log.h new file mode 100644 index 0000000000..b3cd2e7563 --- /dev/null +++ b/include/hw/tpm/tpm_log.h @@ -0,0 +1,89 @@ +#ifndef QEMU_TPM_LOG_H +#define QEMU_TPM_LOG_H + +#include "qom/object.h" +#include "sysemu/tpm.h" + +/* + * Defined in: TCG Algorithm Registry + * Family 2.0 Level 00 Revision 01.34 + * + * (Here TCG stands for Trusted Computing Group) + */ +#define TCG_ALG_SHA256 0xB +#define TCG_ALG_SHA512 0xD + +/* Size of a digest in bytes */ +#define TCG_ALG_SHA256_DIGEST_SIZE 32 +#define TCG_ALG_SHA512_DIGEST_SIZE 64 + +/* + * Defined in: TCG PC Client Platform Firmware Profile Specification + * Version 1.06 revision 52 + */ +#define TCG_EV_NO_ACTION 0x00000003 +#define TCG_EV_EVENT_TAG 0x00000006 +#define TCG_EV_POST_CODE2 0x00000013 +#define TCG_EV_EFI_PLATFORM_FIRMWARE_BLOB2 0x8000000A + +struct UefiPlatformFirmwareBlob2Head { + uint8_t blob_description_size; + uint8_t blob_description[]; +} __attribute__((packed)); + +struct UefiPlatformFirmwareBlob2Tail { + uint64_t blob_base; + uint64_t blob_size; +} __attribute__((packed)); + +#define TYPE_TPM_LOG "tpm-log" + +OBJECT_DECLARE_SIMPLE_TYPE(TpmLog, TPM_LOG) + +/** + * tpm_log_create - Create the event log + * @log: the log object + * @max_size: maximum size of the log. Adding an event past that size will + * return an error + * @errp: pointer to a NULL-initialized error object + * + * Allocate the event log and create the initial entry (Spec ID Event03) + * describing the log format. + * + * Returns: 0 on success, -1 on error + */ +int tpm_log_create(TpmLog *log, size_t max_size, Error **errp); + +/** + * tpm_log_add_event - Append an event to the log + * @log: the log object + * @event_type: the `eventType` field in TCG_PCR_EVENT2 + * @event: the `event` field in TCG_PCR_EVENT2 + * @event_size: the `eventSize` field in TCG_PCR_EVENT2 + * @data: content to be hashed into the event digest. May be NULL. + * @data_size: size of @data. Should be zero when @data is NULL. + * @errp: pointer to a NULL-initialized error object + * + * Add a TCG_PCR_EVENT2 event to the event log. Depending on the event type, a + * data buffer may be hashed into the event digest (for example + * TCG_EV_EFI_PLATFORM_FIRMWARE_BLOB2 contains a digest of the blob.) + * + * Returns: 0 on success, -1 on error + */ +int tpm_log_add_event(TpmLog *log, uint32_t event_type, const uint8_t *event, + size_t event_size, const uint8_t *data, size_t data_size, + Error **errp); + +/** + * tpm_log_write_and_close - Move the log to guest memory + * @log: the log object + * @errp: pointer to a NULL-initialized error object + * + * Write the log into memory, at the address set in the load-addr property. + * After this operation, the log is not writable anymore. + * + * Return: 0 on success, -1 on error + */ +int tpm_log_write_and_close(TpmLog *log, Error **errp); + +#endif diff --git a/hw/tpm/tpm_log.c b/hw/tpm/tpm_log.c new file mode 100644 index 0000000000..e6183a6e70 --- /dev/null +++ b/hw/tpm/tpm_log.c @@ -0,0 +1,325 @@ +/* + * tpm_log.c - Event log as described by the Trusted Computing Group (TCG) + * + * Copyright (c) 2024 Linaro Ltd. + * + * This work is licensed under the terms of the GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + * Create an event log in the format specified by: + * + * TCG PC Client Platform Firmware Profile Specification + * Level 00 Version 1.06 Revision 52 + * Family “2.0” + */ + +#include "qemu/osdep.h" + +#include "crypto/hash.h" +#include "exec/address-spaces.h" +#include "exec/memory.h" +#include "hw/tpm/tpm_log.h" +#include "qapi/error.h" +#include "qemu/bswap.h" +#include "qom/object_interfaces.h" + +/* + * Legacy structure used only in the first event in the log, for compatibility + */ +struct TcgPcClientPcrEvent { + uint32_t pcr_index; + uint32_t event_type; + uint8_t digest[20]; + uint32_t event_data_size; + uint8_t event[]; +} __attribute__((packed)); + +struct TcgEfiSpecIdEvent { + uint8_t signature[16]; + uint32_t platform_class; + uint8_t family_version_minor; + uint8_t family_version_major; + uint8_t spec_revision; + uint8_t uintn_size; + uint32_t number_of_algorithms; /* 1 */ + /* + * For now we declare a single algo, but if we want UEFI to reuse this + * header then we'd need to add entries here for all algos supported by + * UEFI (and expand the digest field for EV_NO_ACTION). + */ + uint16_t algorithm_id; + uint16_t digest_size; + uint8_t vendor_info_size; + uint8_t vendor_info[]; +} __attribute__((packed)); + +struct TcgPcrEvent2Head { + uint32_t pcr_index; + uint32_t event_type; + /* variable-sized digests */ + uint8_t digests[]; +} __attribute__((packed)); + +struct TcgPcrEvent2Tail { + uint32_t event_size; + uint8_t event[]; +} __attribute__((packed)); + +struct TpmlDigestValues { + uint32_t count; /* 1 */ + uint16_t hash_alg; + uint8_t digest[]; +} __attribute__((packed)); + +struct TpmLog { + Object parent_obj; + + TpmLogDigestAlgo digest_algo; + size_t max_size; + uint64_t load_addr; + + uint16_t tcg_algo; + GByteArray *content; + uint8_t *digest; + size_t digest_size; +}; + +OBJECT_DEFINE_SIMPLE_TYPE(TpmLog, tpm_log, TPM_LOG, OBJECT) + +static void tpm_log_init(Object *obj) +{ + TpmLog *log = TPM_LOG(obj); + + log->digest_algo = TPM_LOG_DIGEST_ALGO_SHA256; +} + +static void tpm_log_destroy(TpmLog *log) +{ + if (!log->content) { + return; + } + g_free(log->digest); + log->digest = NULL; + g_byte_array_free(log->content, /* free_segment */ true); + log->content = NULL; +} + +static void tpm_log_finalize(Object *obj) +{ + tpm_log_destroy(TPM_LOG(obj)); +} + +static int tpm_log_get_digest_algo(Object *obj, Error **errp) +{ + TpmLog *log = TPM_LOG(obj); + + return log->digest_algo; +} + +static void tpm_log_set_digest_algo(Object *obj, int algo, Error **errp) +{ + TpmLog *log = TPM_LOG(obj); + + if (log->content != NULL) { + error_setg(errp, "cannot set digest algo after log creation"); + return; + } + + log->digest_algo = algo; +} + +static void tpm_log_get_max_size(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) +{ + TpmLog *log = TPM_LOG(obj); + uint64_t value = log->max_size; + + visit_type_uint64(v, name, &value, errp); +} + +static void tpm_log_get_load_addr(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) +{ + TpmLog *log = TPM_LOG(obj); + uint64_t value = log->load_addr; + + visit_type_uint64(v, name, &value, errp); +} + +static void tpm_log_set_load_addr(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) +{ + TpmLog *log = TPM_LOG(obj); + uint64_t value; + + if (!visit_type_uint64(v, name, &value, errp)) { + return; + } + + log->load_addr = value; +} + + +static void tpm_log_class_init(ObjectClass *oc, void *data) +{ + object_class_property_add_enum(oc, "digest-algo", + "TpmLogDigestAlgo", + &TpmLogDigestAlgo_lookup, + tpm_log_get_digest_algo, + tpm_log_set_digest_algo); + object_class_property_set_description(oc, "digest-algo", + "Algorithm used to hash blobs added as events ('sha256', 'sha512')"); + + /* max_size is set while allocating the log in tpm_log_create */ + object_class_property_add(oc, "max-size", "uint64", tpm_log_get_max_size, + NULL, NULL, NULL); + object_class_property_set_description(oc, "max-size", + "Maximum size of the log, reserved in guest memory"); + + object_class_property_add(oc, "load-addr", "uint64", tpm_log_get_load_addr, + tpm_log_set_load_addr, NULL, NULL); + object_class_property_set_description(oc, "load-addr", + "Base address of the log in guest memory"); +} + +int tpm_log_create(TpmLog *log, size_t max_size, Error **errp) +{ + struct TcgEfiSpecIdEvent event; + struct TcgPcClientPcrEvent header = { + .pcr_index = 0, + .event_type = cpu_to_le32(TCG_EV_NO_ACTION), + .digest = {0}, + .event_data_size = cpu_to_le32(sizeof(event)), + }; + + log->content = g_byte_array_sized_new(max_size); + log->max_size = max_size; + + switch (log->digest_algo) { + case TPM_LOG_DIGEST_ALGO_SHA256: + log->tcg_algo = TCG_ALG_SHA256; + log->digest_size = TCG_ALG_SHA256_DIGEST_SIZE; + break; + case TPM_LOG_DIGEST_ALGO_SHA512: + log->tcg_algo = TCG_ALG_SHA512; + log->digest_size = TCG_ALG_SHA512_DIGEST_SIZE; + break; + default: + g_assert_not_reached(); + } + + log->digest = g_malloc0(log->digest_size); + + event = (struct TcgEfiSpecIdEvent) { + .signature = "Spec ID Event03", + .platform_class = 0, + .family_version_minor = 0, + .family_version_major = 2, + .spec_revision = 106, + .uintn_size = 2, /* UINT64 */ + .number_of_algorithms = cpu_to_le32(1), + .algorithm_id = cpu_to_le16(log->tcg_algo), + .digest_size = cpu_to_le16(log->digest_size), + .vendor_info_size = 0, + }; + + g_byte_array_append(log->content, (guint8 *)&header, sizeof(header)); + g_byte_array_append(log->content, (guint8 *)&event, sizeof(event)); + return 0; +} + +int tpm_log_add_event(TpmLog *log, uint32_t event_type, const uint8_t *event, + size_t event_size, const uint8_t *data, size_t data_size, + Error **errp) +{ + int digests = 0; + size_t rollback_len; + struct TcgPcrEvent2Head header = { + .pcr_index = 0, + .event_type = cpu_to_le32(event_type), + }; + struct TpmlDigestValues digest_header = {0}; + struct TcgPcrEvent2Tail tail = { + .event_size = cpu_to_le32(event_size), + }; + + if (log->content == NULL) { + error_setg(errp, "event log is not initialized"); + return -EINVAL; + } + rollback_len = log->content->len; + + g_byte_array_append(log->content, (guint8 *)&header, sizeof(header)); + + if (data) { + QCryptoHashAlgo qc_algo; + + digest_header.hash_alg = cpu_to_le16(log->tcg_algo); + switch (log->digest_algo) { + case TPM_LOG_DIGEST_ALGO_SHA256: + qc_algo = QCRYPTO_HASH_ALGO_SHA256; + break; + case TPM_LOG_DIGEST_ALGO_SHA512: + qc_algo = QCRYPTO_HASH_ALGO_SHA512; + break; + default: + g_assert_not_reached(); + } + if (qcrypto_hash_bytes(qc_algo, (const char *)data, data_size, + &log->digest, &log->digest_size, errp)) { + goto err_rollback; + } + digests = 1; + } else if (event_type == TCG_EV_NO_ACTION) { + /* EV_NO_ACTION contains empty digests for each supported algo */ + memset(log->digest, 0, log->digest_size); + digest_header.hash_alg = 0; + digests = 1; + } + + if (digests) { + digest_header.count = cpu_to_le32(digests); + g_byte_array_append(log->content, (guint8 *)&digest_header, + sizeof(digest_header)); + g_byte_array_append(log->content, log->digest, log->digest_size); + } else { + /* Add an empty digests list */ + g_byte_array_append(log->content, (guint8 *)&digest_header.count, + sizeof(digest_header.count)); + } + + g_byte_array_append(log->content, (guint8 *)&tail, sizeof(tail)); + g_byte_array_append(log->content, event, event_size); + + if (log->content->len > log->max_size) { + error_setg(errp, "event log exceeds max size"); + goto err_rollback; + } + + return 0; + +err_rollback: + g_byte_array_set_size(log->content, rollback_len); + return -1; +} + +int tpm_log_write_and_close(TpmLog *log, Error **errp) +{ + int ret; + + if (!log->content) { + error_setg(errp, "event log is not initialized"); + return -1; + } + + ret = address_space_write_rom(&address_space_memory, log->load_addr, + MEMTXATTRS_UNSPECIFIED, log->content->data, + log->content->len); + if (ret) { + error_setg(errp, "cannot load log into memory"); + return -1; + } + + tpm_log_destroy(log); + return ret; +} diff --git a/hw/tpm/Kconfig b/hw/tpm/Kconfig index a46663288c..70694b14a3 100644 --- a/hw/tpm/Kconfig +++ b/hw/tpm/Kconfig @@ -30,3 +30,7 @@ config TPM_SPAPR default y depends on TPM && PSERIES select TPM_BACKEND + +config TPM_LOG + bool + default y diff --git a/hw/tpm/meson.build b/hw/tpm/meson.build index 6968e60b3f..81efb557f3 100644 --- a/hw/tpm/meson.build +++ b/hw/tpm/meson.build @@ -6,4 +6,5 @@ system_ss.add(when: 'CONFIG_TPM_CRB', if_true: files('tpm_crb.c')) system_ss.add(when: 'CONFIG_TPM_TIS', if_true: files('tpm_ppi.c')) system_ss.add(when: 'CONFIG_TPM_CRB', if_true: files('tpm_ppi.c')) +system_ss.add(when: 'CONFIG_TPM_LOG', if_true: files('tpm_log.c')) specific_ss.add(when: 'CONFIG_TPM_SPAPR', if_true: files('tpm_spapr.c')) From patchwork Mon Nov 25 19:56:23 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Philippe Brucker X-Patchwork-Id: 13885238 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 023C0D59D67 for ; Mon, 25 Nov 2024 20:05:02 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tFfFP-0005JX-L3; Mon, 25 Nov 2024 14:59:51 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tFfFK-0005En-Hi for qemu-devel@nongnu.org; Mon, 25 Nov 2024 14:59:46 -0500 Received: from mail-wr1-x431.google.com ([2a00:1450:4864:20::431]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1tFfFD-0004t3-OF for qemu-devel@nongnu.org; Mon, 25 Nov 2024 14:59:46 -0500 Received: by mail-wr1-x431.google.com with SMTP id ffacd0b85a97d-382442b7d9aso3702400f8f.1 for ; Mon, 25 Nov 2024 11:59:39 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1732564778; x=1733169578; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=+uO/papoLLk0b3uqMB8ZdXvs73vVNVF+lSFeGHBI0zI=; b=OhLABPK0bpZqrobwEtOOLMTKOkMVtkJ5E7s1GUlIG6BExVa7kBportjf1o4p578c5i c1yiJORL9E2+FOSULKNlW+m6rTnMFmLY9cUpTMxZBXhp6Fn4Cha96b2NKzh7JxxlVDkf LDFd012ecJThVk2mhIexaaZa+huU9GvCJASXDIMl5TsyBq8O/sX5ojAZkfnx9OaENrX/ XdsfnWLqjehD45XJyZJbwR9i7k+DaUvq5sb9NY3viFJ4Sszp6JwCJFFqaIHPoZ2gdHf1 Bz9gXBeHHZcKDMcAECk+FgL0CL43V4Gph6I/l0460RVkM3wRzIw03qavu+mcQfwKsMC+ k39Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1732564778; x=1733169578; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=+uO/papoLLk0b3uqMB8ZdXvs73vVNVF+lSFeGHBI0zI=; b=OIn6yHfbJWPNaEB1p6eR35ThMxHjD22iOEAqcqjSfUUGdBoOhADR3ibbKrLA9zoGLc 8Hv4Kk36jk7pLknvqScHdefJwthsn9KVvg94Dai155YVg3VtwEstdDJgCHZlQQAtfvRA u6sn8chfBYJ5e5CQGCImNz945k0DcqXuxsxcgey+ZR96xZKHotY4g1dE1wPyFn6jlPil op/RAwdUrTUhjjL5hCxDbrEmiGYBXphuj66TnKpYgYkTyotCpb0Mn22RL1eYnmqB9nOl pMQeVU85HmT0HlNMLfrbbpRwSOog1IDw7fP128VJEv4yxhBG/RLCXglquWbxcuBNmZ/9 arNA== X-Forwarded-Encrypted: i=1; AJvYcCUAAlaAmrzehqdVI8fYx/N30hmCZGZoeRuGhXOt7WrzDFVO0IhzkPFMlt3SIgMobMau3+xjiZx/iQ3I@nongnu.org X-Gm-Message-State: AOJu0YztX1TU9GW3v0mH108Ezkvvs7wb0dWFMwcJ3KzRZ6Ur/x7Xe8ZS GG0MaB6asyPFwHFD92BGP9L3PrqzZ8Hz+3FKQ27xvGKtn6BQb+wNeZXFbgUfbFk= X-Gm-Gg: ASbGnctMHZ3ueQXosvC1Tl7tX+LgCP0ma2MpbNsTfiKqevMYBhNGKibe1PCKOz5zThv a3ITWZPcff9laaZWaOI/4joqTpnZEDhbWHOxIFeH6M81jWL6PVj9B/6OQLp9IdhZ2U7yeyzdyYK XWfJag/rLhE3EMJwLTj2Lnd+gAokoHLIzeVOH207b/DLFVFjZ7FmAPcUyYBLIuMxRPQViJel3CE xFn5Wx/btD5tBRmearkOSmh6h6vXUK81R+Eb1mnUbpOfTwS5De49lcytUbqoyVACyJ+ X-Google-Smtp-Source: AGHT+IGczDRNS0/GYso0gUYtSQC3fi60MTtYP0+QSa7oHPzr77RTsYNzR/7WGuk/JJO1HJo4LUm2pg== X-Received: by 2002:a05:6000:1541:b0:382:2f62:bd45 with SMTP id ffacd0b85a97d-38260b70e7emr10262936f8f.29.1732564778383; Mon, 25 Nov 2024 11:59:38 -0800 (PST) Received: from localhost.localdomain ([2.221.137.100]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3825fd0fbdcsm11237971f8f.109.2024.11.25.11.59.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 25 Nov 2024 11:59:38 -0800 (PST) From: Jean-Philippe Brucker To: peter.maydell@linaro.org Cc: richard.henderson@linaro.org, philmd@linaro.org, qemu-arm@nongnu.org, qemu-devel@nongnu.org, alex.bennee@linaro.org, Jean-Philippe Brucker Subject: [RFC PATCH v3 24/26] hw/core/loader: Add fields to RomLoaderNotify Date: Mon, 25 Nov 2024 19:56:23 +0000 Message-ID: <20241125195626.856992-26-jean-philippe@linaro.org> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241125195626.856992-2-jean-philippe@linaro.org> References: <20241125195626.856992-2-jean-philippe@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::431; envelope-from=jean-philippe@linaro.org; helo=mail-wr1-x431.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org In order to write an event log, the ROM load notification handler needs two more fields. Signed-off-by: Jean-Philippe Brucker --- v2->v3: New --- include/hw/loader.h | 2 ++ hw/core/loader.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/include/hw/loader.h b/include/hw/loader.h index 0cd9905f97..73f317966d 100644 --- a/include/hw/loader.h +++ b/include/hw/loader.h @@ -355,6 +355,8 @@ ssize_t rom_add_option(const char *file, int32_t bootindex); typedef struct RomLoaderNotify { /* Parameters passed to rom_add_blob() */ + const char *name; + uint8_t *data; hwaddr addr; size_t len; size_t max_len; diff --git a/hw/core/loader.c b/hw/core/loader.c index 759a62cf58..4ff40e8762 100644 --- a/hw/core/loader.c +++ b/hw/core/loader.c @@ -1278,6 +1278,8 @@ static void rom_reset(void *unused) trace_loader_write_rom(rom->name, rom->addr, rom->datasize, rom->isrom); notify = (RomLoaderNotify) { + .name = rom->name, + .data = rom->data, .addr = rom->addr, .len = rom->datasize, .max_len = rom->romsize, From patchwork Mon Nov 25 19:56:24 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Philippe Brucker X-Patchwork-Id: 13885235 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 42C6BD59D67 for ; Mon, 25 Nov 2024 20:04:56 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tFfFV-0005YB-1C; Mon, 25 Nov 2024 14:59:57 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tFfFM-0005GM-FM for qemu-devel@nongnu.org; Mon, 25 Nov 2024 14:59:48 -0500 Received: from mail-wr1-x435.google.com ([2a00:1450:4864:20::435]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1tFfFE-0004tg-Ma for qemu-devel@nongnu.org; Mon, 25 Nov 2024 14:59:48 -0500 Received: by mail-wr1-x435.google.com with SMTP id ffacd0b85a97d-38230ed9baeso3430553f8f.1 for ; Mon, 25 Nov 2024 11:59:40 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1732564779; x=1733169579; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=ALXm5gT4o4ottyTAX8gsvkIohjiJpUzrZLVD6VBNRS8=; b=X7Uo06ABZK1Pt/8oOVUjsBLGNGMTVTnz20RMNLxx61WPQmfnX0mgT1F4IIqbS/2jC5 bjr15yEYMZNUpfuJijAROk21YSqevqAwmuDm77Bz/5tBbZaehPf+HfPRBHFb1JnQgLIE 9WMYdiZWYZehjBwswBDssLgfmnaTiw6OBySbAkcOE7RiA+Rwvk28noTWIthNzoL0job+ tL1i26I16yG2mK3Sgxdv9f3xbSMDlTNtI6Nu8+GrzKwvWWuPSADXQexkQiRcZRroW7r3 T745q38WGyMP9LTp7V9VB234ZZDSG++Dqp+RgfzlYIvLM5sl5BJb8qICOxefD2M5zKZU G88A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1732564779; x=1733169579; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ALXm5gT4o4ottyTAX8gsvkIohjiJpUzrZLVD6VBNRS8=; b=eoHW7PSKYiHwT/xAqNFFoJUhLrflEHIoE4L3IvvKrfXRgoiUQlffVmWh7odaZEb2+z In60+DVuSAQTQ0+iGwDTpQIQGSbdncRtIKt4qgC51S6ZFSvHld9Fv+LU4in6a2e0w43e z1Nr7nszeTVoLJ6tLnbYsdmUSsF6IVqiMnY5LBqT9HI1CDDjaT6l9qOLoijRF5WDiEbB Qots2P42WqTLKfUPKQ2bcAFOQTKKLgc7IAQqaxVuZFywLxwDihznoYmm311uREYETbLG jEgKXPwRfPwNWYPwhlRVgTydDlE9HXX6cDIPFDaIfbPQ9W9DG2MzYuavnJGyJqMGa85W TEJg== X-Forwarded-Encrypted: i=1; AJvYcCVjooJb0bYVWZg3nSaxkrxh/wxMOkzpJe6yJCskdfyZMhi0XO01CGLB0NXjuZe5ejXZ1uWvnOcXgJPb@nongnu.org X-Gm-Message-State: AOJu0Yw59x1oT8xvVOXyz9ixdz2dg940UfEJZGOPaqSEpjWmOIY9yirQ T07uMS4wQW2l34QzvVYV3K54bg0y1wqlOwIuM3TF2AvVMbBTW/vcFSx/1bXBsWE= X-Gm-Gg: ASbGncsPjSaYn3Vs3fbut7/L6GSaPwB9Ycp1q7oM+SkwN53c92eLdlhYhlzOLD4FfUC SoMMKh+K2TLXcOPm7rD9tQWHndJu8JTE85JkGoCjfTIr89V8khYvFcD5tI/rG/ys+i4Ze7upkAg cmf2FqKQCNUqlyIo1qSSViX9oMa0CGQUuNm8HvkgCt/S8NlmIEQmqiMmhJBnY7dZFSwcouPinQl Sx3Cw5LCpcd3tBKA2TPnexbVTrPmISwWuUXS3aBVaJrmoSu9fMrsPuCwFlaHqdwDD8Z X-Google-Smtp-Source: AGHT+IFdM1ybdFtANnY9CTfKcwxW+1igpXzLDtGHgjomaSS2YBTfeFzVZDrWVuBP9gt7reepJifQMQ== X-Received: by 2002:a5d:59a3:0:b0:382:5036:d1f2 with SMTP id ffacd0b85a97d-38260be3fbbmr13015033f8f.54.1732564779026; Mon, 25 Nov 2024 11:59:39 -0800 (PST) Received: from localhost.localdomain ([2.221.137.100]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3825fd0fbdcsm11237971f8f.109.2024.11.25.11.59.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 25 Nov 2024 11:59:38 -0800 (PST) From: Jean-Philippe Brucker To: peter.maydell@linaro.org Cc: richard.henderson@linaro.org, philmd@linaro.org, qemu-arm@nongnu.org, qemu-devel@nongnu.org, alex.bennee@linaro.org, Jean-Philippe Brucker , Stefan Berger Subject: [RFC PATCH v3 25/26] target/arm/kvm-rme: Add measurement log Date: Mon, 25 Nov 2024 19:56:24 +0000 Message-ID: <20241125195626.856992-27-jean-philippe@linaro.org> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241125195626.856992-2-jean-philippe@linaro.org> References: <20241125195626.856992-2-jean-philippe@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::435; envelope-from=jean-philippe@linaro.org; helo=mail-wr1-x435.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Create an event log, in the format defined by Trusted Computing Group for TPM2. It contains information about the VMM, the Realm parameters, any data loaded into guest memory before boot and the initial vCPU state. The guest can access this log from RAM and send it to a verifier, to help the verifier independently compute the Realm Initial Measurement, and check that the data we load into guest RAM is known-good images. Without this log, the verifier has to guess where everything is loaded and in what order. Cc: Stefan Berger Signed-off-by: Jean-Philippe Brucker --- v2->v3: New --- qapi/qom.json | 9 +- target/arm/kvm_arm.h | 27 +++ target/arm/kvm-rme.c | 415 ++++++++++++++++++++++++++++++++++++++++++- target/arm/Kconfig | 1 + 4 files changed, 449 insertions(+), 3 deletions(-) diff --git a/qapi/qom.json b/qapi/qom.json index 901ba67634..1de1b0d8af 100644 --- a/qapi/qom.json +++ b/qapi/qom.json @@ -1094,11 +1094,18 @@ # @measurement-algorithm: Realm measurement algorithm # (default: sha512) # +# @measurement-log: Enable a measurement log for the Realm. All events +# that contribute to the Realm Initial Measurement (RIM) are added +# to a log in TCG TPM2 format, which is itself loaded into Realm +# memory (unmeasured) and can then be read by a verifier to +# reconstruct the RIM. +# # Since: 9.3 ## { 'struct': 'RmeGuestProperties', 'data': { '*personalization-value': 'str', - '*measurement-algorithm': 'RmeGuestMeasurementAlgorithm' } } + '*measurement-algorithm': 'RmeGuestMeasurementAlgorithm', + '*measurement-log': 'bool'} } ## # @ObjectType: diff --git a/target/arm/kvm_arm.h b/target/arm/kvm_arm.h index 77680f238a..44e95a034b 100644 --- a/target/arm/kvm_arm.h +++ b/target/arm/kvm_arm.h @@ -268,6 +268,24 @@ int kvm_arm_rme_vcpu_init(CPUState *cs); */ void kvm_arm_rme_init_guest_ram(hwaddr base, size_t size); +/** + * kvm_arm_rme_get_measurement_log + * + * Obtain the measurement log object if enabled, in order to get its size and + * set its base address. + * + * Returns NULL if measurement log is disabled. + */ +Object *kvm_arm_rme_get_measurement_log(void); + +/** + * kvm_arm_rme_set_ipa_size + * @ipa_bits: number of guest physical address bits + * + * Set the GPA size, not counting the bit reserved for shared address range. + */ +void kvm_arm_rme_set_ipa_size(uint8_t ipa_bits); + #else /* @@ -298,6 +316,15 @@ static inline void kvm_arm_rme_init_guest_ram(hwaddr base, size_t size) { } +static inline Object *kvm_arm_rme_get_measurement_log(void) +{ + return NULL; +} + +static inline void kvm_arm_rme_set_ipa_size(uint8_t ipa_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 bf0bcf9a38..f92cfdb5f3 100644 --- a/target/arm/kvm-rme.c +++ b/target/arm/kvm-rme.c @@ -10,10 +10,12 @@ #include "hw/boards.h" #include "hw/core/cpu.h" #include "hw/loader.h" +#include "hw/tpm/tpm_log.h" #include "kvm_arm.h" #include "migration/blocker.h" #include "qapi/error.h" #include "qemu/error-report.h" +#include "qemu/units.h" #include "qom/object_interfaces.h" #include "sysemu/kvm.h" #include "sysemu/runstate.h" @@ -25,6 +27,8 @@ OBJECT_DECLARE_SIMPLE_TYPE(RmeGuest, RME_GUEST) #define RME_MAX_CFG 2 +#define RME_MEASUREMENT_LOG_SIZE (64 * KiB) + struct RmeGuest { ConfidentialGuestSupport parent_obj; Notifier rom_load_notifier; @@ -32,22 +36,344 @@ struct RmeGuest { uint8_t *personalization_value; RmeGuestMeasurementAlgorithm measurement_algo; + bool use_measurement_log; + size_t num_cpus; + uint8_t ipa_bits; hwaddr ram_base; size_t ram_size; + + TpmLog *log; + GHashTable *images; }; OBJECT_DEFINE_SIMPLE_TYPE_WITH_INTERFACES(RmeGuest, rme_guest, RME_GUEST, CONFIDENTIAL_GUEST_SUPPORT, { TYPE_USER_CREATABLE }, { }) +typedef struct RmeLogFiletype { + uint32_t event_type; + /* Description copied into the log event */ + const char *desc; +} RmeLogFiletype; + typedef struct { hwaddr base; hwaddr size; + uint8_t *data; + RmeLogFiletype *filetype; } RmeRamRegion; +typedef struct { + char signature[16]; + char name[32]; + char version[40]; + uint64_t ram_size; + uint32_t num_cpus; + uint64_t flags; +} EventLogVmmVersion; + +typedef struct { + uint32_t id; + uint32_t data_size; + uint8_t data[]; +} EventLogTagged; + +#define EVENT_LOG_TAG_REALM_CREATE 1 +#define EVENT_LOG_TAG_INIT_RIPAS 2 +#define EVENT_LOG_TAG_REC_CREATE 3 + +#define REALM_PARAMS_FLAG_SVE (1 << 1) +#define REALM_PARAMS_FLAG_PMU (1 << 2) + +#define REC_CREATE_FLAG_RUNNABLE (1 << 0) + static RmeGuest *rme_guest; +static int rme_init_measurement_log(MachineState *ms) +{ + Object *log; + gpointer filename; + TpmLogDigestAlgo algo; + RmeLogFiletype *filetype; + + if (!rme_guest->use_measurement_log) { + return 0; + } + + switch (rme_guest->measurement_algo) { + case RME_GUEST_MEASUREMENT_ALGORITHM_SHA256: + algo = TPM_LOG_DIGEST_ALGO_SHA256; + break; + case RME_GUEST_MEASUREMENT_ALGORITHM_SHA512: + algo = TPM_LOG_DIGEST_ALGO_SHA512; + break; + default: + g_assert_not_reached(); + } + + log = object_new_with_props(TYPE_TPM_LOG, OBJECT(rme_guest), + "log", &error_fatal, + "digest-algo", TpmLogDigestAlgo_str(algo), + NULL); + + tpm_log_create(TPM_LOG(log), RME_MEASUREMENT_LOG_SIZE, &error_fatal); + rme_guest->log = TPM_LOG(log); + + /* + * Write down the image names we're expecting to encounter when handling the + * ROM load notifications, so we can record the type of image being loaded + * to help the verifier. + */ + rme_guest->images = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, + g_free); + + filename = g_strdup(ms->kernel_filename); + if (filename) { + filetype = g_new0(RmeLogFiletype, 1); + filetype->event_type = TCG_EV_POST_CODE2; + filetype->desc = "KERNEL"; + g_hash_table_insert(rme_guest->images, filename, (gpointer)filetype); + } + + filename = g_strdup(ms->initrd_filename); + if (filename) { + filetype = g_new0(RmeLogFiletype, 1); + filetype->event_type = TCG_EV_POST_CODE2; + filetype->desc = "INITRD"; + g_hash_table_insert(rme_guest->images, filename, (gpointer)filetype); + } + + filename = g_strdup(ms->firmware); + if (filename) { + filetype = g_new0(RmeLogFiletype, 1); + filetype->event_type = TCG_EV_EFI_PLATFORM_FIRMWARE_BLOB2; + filetype->desc = "FIRMWARE"; + g_hash_table_insert(rme_guest->images, filename, filetype); + } + + filename = g_strdup(ms->dtb); + if (!filename) { + filename = g_strdup("dtb"); + } + filetype = g_new0(RmeLogFiletype, 1); + filetype->event_type = TCG_EV_POST_CODE2; + filetype->desc = "DTB"; + g_hash_table_insert(rme_guest->images, filename, filetype); + + return 0; +} + +static int rme_log_event_tag(uint32_t id, uint8_t *data, size_t size, + Error **errp) +{ + int ret; + EventLogTagged event = { + .id = id, + .data_size = size, + }; + GByteArray *bytes = g_byte_array_new(); + + if (!rme_guest->log) { + return 0; + } + + g_byte_array_append(bytes, (uint8_t *)&event, sizeof(event)); + g_byte_array_append(bytes, data, size); + ret = tpm_log_add_event(rme_guest->log, TCG_EV_EVENT_TAG, bytes->data, + bytes->len, NULL, 0, errp); + g_byte_array_free(bytes, true); + return ret; +} + +/* Log VM type and Realm Descriptor create */ +static int rme_log_realm_create(Error **errp) +{ + int ret; + ARMCPU *cpu; + EventLogVmmVersion vmm_version = { + .signature = "VM VERSION", + .name = "QEMU", + .version = "9.1", /* TODO: dynamic */ + .ram_size = cpu_to_le64(rme_guest->ram_size), + .num_cpus = cpu_to_le32(rme_guest->num_cpus), + .flags = 0, + }; + struct { + uint64_t flags; + uint8_t s2sz; + uint8_t sve_vl; + uint8_t num_bps; + uint8_t num_wps; + uint8_t pmu_num_ctrs; + uint8_t hash_algo; + } params = { + .s2sz = rme_guest->ipa_bits, + }; + + if (!rme_guest->log) { + return 0; + } + + ret = tpm_log_add_event(rme_guest->log, TCG_EV_NO_ACTION, + (uint8_t *)&vmm_version, sizeof(vmm_version), + NULL, 0, errp); + if (ret) { + return ret; + } + + /* With KVM all CPUs have the same capability */ + cpu = ARM_CPU(first_cpu); + if (cpu->has_pmu) { + params.flags |= REALM_PARAMS_FLAG_PMU; + params.pmu_num_ctrs = FIELD_EX64(cpu->isar.reset_pmcr_el0, PMCR, N); + } + + if (cpu->sve_max_vq) { + params.flags |= REALM_PARAMS_FLAG_SVE; + params.sve_vl = cpu->sve_max_vq - 1; + } + params.num_bps = FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, BRPS); + params.num_wps = FIELD_EX64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, WRPS); + + switch (rme_guest->measurement_algo) { + case RME_GUEST_MEASUREMENT_ALGORITHM_SHA256: + params.hash_algo = KVM_CAP_ARM_RME_MEASUREMENT_ALGO_SHA256; + break; + case RME_GUEST_MEASUREMENT_ALGORITHM_SHA512: + params.hash_algo = KVM_CAP_ARM_RME_MEASUREMENT_ALGO_SHA512; + break; + default: + g_assert_not_reached(); + } + + return rme_log_event_tag(EVENT_LOG_TAG_REALM_CREATE, (uint8_t *)¶ms, + sizeof(params), errp); +} + +/* unmeasured images are logged with @data == NULL */ +static int rme_log_image(RmeLogFiletype *filetype, uint8_t *data, hwaddr base, + size_t size, Error **errp) +{ + int ret; + size_t desc_size; + GByteArray *event = g_byte_array_new(); + struct UefiPlatformFirmwareBlob2Head head = {0}; + struct UefiPlatformFirmwareBlob2Tail tail = {0}; + + if (!rme_guest->log) { + return 0; + } + + if (!filetype) { + error_setg(errp, "cannot log image without a filetype"); + return -1; + } + + /* EV_POST_CODE2 strings are not NUL-terminated */ + desc_size = strlen(filetype->desc); + head.blob_description_size = desc_size; + tail.blob_base = cpu_to_le64(base); + tail.blob_size = cpu_to_le64(size); + + g_byte_array_append(event, (guint8 *)&head, sizeof(head)); + g_byte_array_append(event, (guint8 *)filetype->desc, desc_size); + g_byte_array_append(event, (guint8 *)&tail, sizeof(tail)); + + ret = tpm_log_add_event(rme_guest->log, filetype->event_type, event->data, + event->len, data, size, errp); + g_byte_array_free(event, true); + return ret; +} + +static int rme_log_ripas(hwaddr base, size_t size, Error **errp) +{ + struct { + uint64_t base; + uint64_t size; + } init_ripas = { + .base = cpu_to_le64(base), + .size = cpu_to_le64(size), + }; + + return rme_log_event_tag(EVENT_LOG_TAG_INIT_RIPAS, (uint8_t *)&init_ripas, + sizeof(init_ripas), errp); +} + +static int rme_log_rec(uint64_t flags, uint64_t pc, uint64_t gprs[8], Error **errp) +{ + struct { + uint64_t flags; + uint64_t pc; + uint64_t gprs[8]; + } rec_create = { + .flags = cpu_to_le64(flags), + .pc = cpu_to_le64(pc), + .gprs[0] = cpu_to_le64(gprs[0]), + .gprs[1] = cpu_to_le64(gprs[1]), + .gprs[2] = cpu_to_le64(gprs[2]), + .gprs[3] = cpu_to_le64(gprs[3]), + .gprs[4] = cpu_to_le64(gprs[4]), + .gprs[5] = cpu_to_le64(gprs[5]), + .gprs[6] = cpu_to_le64(gprs[6]), + .gprs[7] = cpu_to_le64(gprs[7]), + }; + + return rme_log_event_tag(EVENT_LOG_TAG_REC_CREATE, (uint8_t *)&rec_create, + sizeof(rec_create), errp); +} + +static int rme_populate_range(hwaddr base, size_t size, bool measure, + Error **errp); + +static int rme_close_measurement_log(Error **errp) +{ + int ret; + hwaddr base; + size_t size; + RmeLogFiletype filetype = { + .event_type = TCG_EV_POST_CODE2, + .desc = "LOG", + }; + + if (!rme_guest->log) { + return 0; + } + + base = object_property_get_uint(OBJECT(rme_guest->log), "load-addr", errp); + if (*errp) { + return -1; + } + + size = object_property_get_uint(OBJECT(rme_guest->log), "max-size", errp); + if (*errp) { + return -1; + } + + /* Log the log itself */ + ret = rme_log_image(&filetype, NULL, base, size, errp); + if (ret) { + return ret; + } + + ret = tpm_log_write_and_close(rme_guest->log, errp); + if (ret) { + return ret; + } + + ret = rme_populate_range(base, size, /* measure */ false, errp); + if (ret) { + return ret; + } + + g_hash_table_destroy(rme_guest->images); + + /* The log is now in the guest. Free this object */ + object_unparent(OBJECT(rme_guest->log)); + rme_guest->log = NULL; + return 0; +} + static int rme_configure_one(RmeGuest *guest, uint32_t cfg, Error **errp) { int ret; @@ -120,9 +446,10 @@ static int rme_init_ram(hwaddr base, size_t size, Error **errp) error_setg_errno(errp, -ret, "failed to init RAM [0x%"HWADDR_PRIx", 0x%"HWADDR_PRIx")", start, end); + return ret; } - return ret; + return rme_log_ripas(base, size, errp); } static int rme_populate_range(hwaddr base, size_t size, bool measure, @@ -158,23 +485,42 @@ static void rme_populate_ram_region(gpointer data, gpointer err) } rme_populate_range(region->base, region->size, /* measure */ true, errp); + if (*errp) { + return; + } + + rme_log_image(region->filetype, region->data, region->base, region->size, + errp); } static int rme_init_cpus(Error **errp) { int ret; CPUState *cs; + bool logged_primary_cpu = false; /* * Now that do_cpu_reset() initialized the boot PC and * kvm_cpu_synchronize_post_reset() registered it, we can finalize the REC. */ CPU_FOREACH(cs) { - ret = kvm_arm_vcpu_finalize(ARM_CPU(cs), KVM_ARM_VCPU_REC); + ARMCPU *cpu = ARM_CPU(cs); + + ret = kvm_arm_vcpu_finalize(cpu, KVM_ARM_VCPU_REC); if (ret) { error_setg_errno(errp, -ret, "failed to finalize vCPU"); return ret; } + + if (!logged_primary_cpu) { + ret = rme_log_rec(REC_CREATE_FLAG_RUNNABLE, cpu->env.pc, + cpu->env.xregs, errp); + if (ret) { + return ret; + } + + logged_primary_cpu = true; + } } return 0; } @@ -194,6 +540,10 @@ static int rme_create_realm(Error **errp) return -1; } + if (rme_log_realm_create(errp)) { + return -1; + } + if (rme_init_ram(rme_guest->ram_base, rme_guest->ram_size, errp)) { return -1; } @@ -208,6 +558,10 @@ static int rme_create_realm(Error **errp) return -1; } + if (rme_close_measurement_log(errp)) { + return -1; + } + ret = kvm_vm_enable_cap(kvm_state, KVM_CAP_ARM_RME, 0, KVM_CAP_ARM_RME_ACTIVATE_REALM); if (ret) { @@ -303,6 +657,20 @@ static void rme_set_measurement_algo(Object *obj, int algo, Error **errp) guest->measurement_algo = algo; } +static bool rme_get_measurement_log(Object *obj, Error **errp) +{ + RmeGuest *guest = RME_GUEST(obj); + + return guest->use_measurement_log; +} + +static void rme_set_measurement_log(Object *obj, bool value, Error **errp) +{ + RmeGuest *guest = RME_GUEST(obj); + + guest->use_measurement_log = value; +} + static void rme_guest_class_init(ObjectClass *oc, void *data) { object_class_property_add_str(oc, "personalization-value", rme_get_rpv, @@ -317,6 +685,12 @@ static void rme_guest_class_init(ObjectClass *oc, void *data) rme_set_measurement_algo); object_class_property_set_description(oc, "measurement-algorithm", "Realm measurement algorithm ('sha256', 'sha512')"); + + object_class_property_add_bool(oc, "measurement-log", + rme_get_measurement_log, + rme_set_measurement_log); + object_class_property_set_description(oc, "measurement-log", + "Enable/disable Realm measurement log"); } static void rme_guest_init(Object *obj) @@ -359,6 +733,20 @@ static void rme_rom_load_notify(Notifier *notifier, void *data) region = g_new0(RmeRamRegion, 1); region->base = rom->addr; region->size = rom->len; + /* + * TODO: double-check lifetime. Is data is still available when we measure + * it, while writing the log. Should be fine since data is kept for the next + * reset. + */ + region->data = rom->data; + + /* + * rme_guest->images is destroyed after ram_regions, so we can store + * filetype even if we don't own the struct. + */ + if (rme_guest->images) { + region->filetype = g_hash_table_lookup(rme_guest->images, rom->name); + } /* * The Realm Initial Measurement (RIM) depends on the order in which we @@ -388,6 +776,13 @@ int kvm_arm_rme_init(MachineState *ms) return -ENODEV; } + if (rme_init_measurement_log(ms)) { + return -ENODEV; + } + + rme_guest->ram_size = ms->ram_size; + rme_guest->num_cpus = ms->smp.max_cpus; + error_setg(&rme_mig_blocker, "RME: migration is not implemented"); migrate_add_blocker(&rme_mig_blocker, &error_fatal); @@ -430,3 +825,19 @@ int kvm_arm_rme_vm_type(MachineState *ms) } return 0; } + +void kvm_arm_rme_set_ipa_size(uint8_t ipa_bits) +{ + if (rme_guest) { + /* We request one more bit to KVM as the NS flag */ + rme_guest->ipa_bits = ipa_bits + 1; + } +} + +Object *kvm_arm_rme_get_measurement_log(void) +{ + if (rme_guest) { + return OBJECT(rme_guest->log); + } + return NULL; +} diff --git a/target/arm/Kconfig b/target/arm/Kconfig index 7f8a2217ae..ee3a2184d0 100644 --- a/target/arm/Kconfig +++ b/target/arm/Kconfig @@ -13,3 +13,4 @@ config AARCH64 select ARM # kvm_arch_fixup_msi_route() needs to access PCIDevice select PCI if KVM + select TPM_LOG if KVM From patchwork Mon Nov 25 19:56:25 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Philippe Brucker X-Patchwork-Id: 13885236 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 2F82DD59D6A for ; Mon, 25 Nov 2024 20:04:58 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tFfFT-0005UP-LA; Mon, 25 Nov 2024 14:59:55 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1tFfFM-0005GL-Fg for qemu-devel@nongnu.org; Mon, 25 Nov 2024 14:59:48 -0500 Received: from mail-wr1-x430.google.com ([2a00:1450:4864:20::430]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1tFfFE-0004tr-TV for qemu-devel@nongnu.org; Mon, 25 Nov 2024 14:59:48 -0500 Received: by mail-wr1-x430.google.com with SMTP id ffacd0b85a97d-382376fcc4fso2823649f8f.2 for ; Mon, 25 Nov 2024 11:59:40 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1732564779; x=1733169579; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Sx/wgUhO2hnEU30pqKphmQJjzDJZvYIKeuvBl/T4ue8=; b=GfO+JlXUCiBEocXmlOnYc0MVFNcxFPDU6qd4i8zU3MvRESadkbT5Kjafu+UQlHOPts IyLYsHe7pEjc7cTK/e/PfZvIE2sVGhPhQ3eKkV9h8gzsiH+EpoebJLHqParFv1ydpxGf ASJo/dAajouef4BFgm/OCABAL0YsPlhm+oiCs3yPnAnN75nonea10J2747WiduFBMFVf NnTCsiG0Yb+gcsw+NZhpOd4JUVEIGstipXSlKc+uqaR20KNNrRK69OktIVaAsMBMLlN9 AL9fJOafVOwV0YaWbtkZhL2prSyGpSnXn/JkP4zpSYqw4B+BJ1g2naQzA+kDrYcuNAme YicQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1732564779; x=1733169579; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Sx/wgUhO2hnEU30pqKphmQJjzDJZvYIKeuvBl/T4ue8=; b=aF47AdqTTMd87SU/QkYwBeXBQ2u8k31JKAcoVabAGIQB92hvcSF5K45eKJD+dMrgZY V2pjzsQ5ibN3FGySzO8aKEvkwU9spfSVoN6e7zclMJDUOPiGm/iD+s542thJQlNXSSBQ zBwDViN/fF9zntLUFFJ6xJqZISb8M0KFZePWiD/JRvKuLe+wBLQv8Tg/fARFS31z/+R2 0zj6iC7KaUrMqjOAPDtr+6M18LehdUZ47oFivnsCofXGQVRmw3+oosiegxsIdGOQ2HH5 /2+clA+XT5Cag8ISkbns+CdgiR4o6On2vb7j1FqelU5YaLxnlhAhrgxQGnPZEzQethvr DxEQ== X-Forwarded-Encrypted: i=1; AJvYcCUFcU8R2uW1IqTzpoxWCF9oKnOkhB+U5t9aWnXX2TjQTn7ARf+SYtfPaZzK0tWpkTwNphoKJm2S1kIl@nongnu.org X-Gm-Message-State: AOJu0Yy7uUG/UVA69GnCimxIPYSrGPJiWNUUVg33963v8BLG0FGd2eCX 4sRRe6mmnTp7iKKjvID0eS9QEGt5LGehSWO0frAK7LnCs7y4IX5Db+z6KXfK9QI= X-Gm-Gg: ASbGnctWycijkpDyGke7yEaDGt7w0yCgmwsqugj85tKacsNuw1H6miUjq+sgb5fA8qV nc+1DsKPZ0XdAilKH6XFaVfg2bUC+L5rADR5UFxcDQfuT+V9mUJrVCt+fPUm3CdB4hCsLF6iDWn suhZQ4KHnBfRkoEtpvycB7CL72WJfBROqvkg+MM/HUB7tyTeOLpP/pPPyydyesmZDc3mOPxn1Ky nmWK7EPH4W6Ca5B0WhlrJBbNlAzKT7RW1GpLhFxQVIqU7UEr6Mslssmu+5lRvLO763P X-Google-Smtp-Source: AGHT+IEDhTtNZEirT7xBFMutfVs/saGMV1bfHmtxSxlCg2GretDVGOBISN5KO8jHbhgqfqZOMilyVg== X-Received: by 2002:a05:6000:18a2:b0:382:496e:8784 with SMTP id ffacd0b85a97d-38260b6eb06mr12571026f8f.26.1732564779568; Mon, 25 Nov 2024 11:59:39 -0800 (PST) Received: from localhost.localdomain ([2.221.137.100]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3825fd0fbdcsm11237971f8f.109.2024.11.25.11.59.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 25 Nov 2024 11:59:39 -0800 (PST) From: Jean-Philippe Brucker To: peter.maydell@linaro.org Cc: richard.henderson@linaro.org, philmd@linaro.org, qemu-arm@nongnu.org, qemu-devel@nongnu.org, alex.bennee@linaro.org, Jean-Philippe Brucker , Stefan Berger Subject: [RFC PATCH v3 26/26] hw/arm/virt: Add measurement log for confidential boot Date: Mon, 25 Nov 2024 19:56:25 +0000 Message-ID: <20241125195626.856992-28-jean-philippe@linaro.org> X-Mailer: git-send-email 2.47.0 In-Reply-To: <20241125195626.856992-2-jean-philippe@linaro.org> References: <20241125195626.856992-2-jean-philippe@linaro.org> MIME-Version: 1.0 Received-SPF: pass client-ip=2a00:1450:4864:20::430; envelope-from=jean-philippe@linaro.org; helo=mail-wr1-x430.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Create a measurement log describing operations performed by QEMU to initialize the guest, and load it into guest memory above the DTB. Cc: Stefan Berger Signed-off-by: Jean-Philippe Brucker --- v2->v3: New --- include/hw/arm/boot.h | 3 +++ include/hw/arm/virt.h | 1 + hw/arm/boot.c | 47 +++++++++++++++++++++++++++++++++++++++++++ hw/arm/virt.c | 23 +++++++++++++++++++++ 4 files changed, 74 insertions(+) diff --git a/include/hw/arm/boot.h b/include/hw/arm/boot.h index 5fcbaa2625..f2518c4e81 100644 --- a/include/hw/arm/boot.h +++ b/include/hw/arm/boot.h @@ -147,6 +147,9 @@ struct arm_boot_info { * Confidential guest boot loads everything into RAM so it can be measured. */ bool confidential; + /* measurement log location in guest memory */ + hwaddr log_start; + size_t log_size; }; /** diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h index e5e9f67f52..fe1c464be6 100644 --- a/include/hw/arm/virt.h +++ b/include/hw/arm/virt.h @@ -180,6 +180,7 @@ struct VirtMachineState { char *oem_id; char *oem_table_id; bool ns_el2_virt_timer_irq; + Object *event_log; }; #define VIRT_ECAM_ID(high) (high ? VIRT_HIGH_PCIE_ECAM : VIRT_PCIE_ECAM) diff --git a/hw/arm/boot.c b/hw/arm/boot.c index e461137595..1ced008062 100644 --- a/hw/arm/boot.c +++ b/hw/arm/boot.c @@ -665,6 +665,24 @@ int arm_load_dtb(hwaddr addr, const struct arm_boot_info *binfo, fdt_add_psci_node(fdt); + /* Add a reserved-memory node for the event log */ + if (binfo->log_size) { + char *nodename; + + qemu_fdt_add_subnode(fdt, "/reserved-memory"); + qemu_fdt_setprop_cell(fdt, "/reserved-memory", "#address-cells", 0x2); + qemu_fdt_setprop_cell(fdt, "/reserved-memory", "#size-cells", 0x2); + qemu_fdt_setprop(fdt, "/reserved-memory", "ranges", NULL, 0); + + nodename = g_strdup_printf("/reserved-memory/event-log@%" PRIx64, + binfo->log_start); + qemu_fdt_add_subnode(fdt, nodename); + qemu_fdt_setprop_string(fdt, nodename, "compatible", "cc-event-log"); + qemu_fdt_setprop_sized_cells(fdt, nodename, "reg", 2, binfo->log_start, + 2, binfo->log_size); + g_free(nodename); + } + if (binfo->modify_dtb) { binfo->modify_dtb(binfo, fdt); } @@ -943,6 +961,30 @@ static uint64_t load_aarch64_image(const char *filename, hwaddr mem_base, return kernel_size; } +static void add_event_log(struct arm_boot_info *info) +{ + if (!info->log_size) { + return; + } + + if (!info->dtb_limit) { + int dtb_size = 0; + + if (!info->get_dtb(info, &dtb_size) || dtb_size == 0) { + error_report("Board does not have a DTB"); + exit(1); + } + info->dtb_limit = info->dtb_start + dtb_size; + } + + info->log_start = info->dtb_limit; + if (info->log_start + info->log_size > + info->loader_start + info->ram_size) { + error_report("Not enough space for measurement log and DTB"); + exit(1); + } +} + static void arm_setup_direct_kernel_boot(ARMCPU *cpu, struct arm_boot_info *info) { @@ -990,6 +1032,7 @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu, } info->dtb_start = info->loader_start; info->dtb_limit = image_low_addr; + add_event_log(info); } } entry = elf_entry; @@ -1128,6 +1171,8 @@ static void arm_setup_direct_kernel_boot(ARMCPU *cpu, error_report("Not enough space for DTB after kernel/initrd"); exit(1); } + add_event_log(info); + fixupcontext[FIXUP_ARGPTR_LO] = info->dtb_start; fixupcontext[FIXUP_ARGPTR_HI] = info->dtb_start >> 32; } else { @@ -1189,6 +1234,8 @@ static void arm_setup_confidential_firmware_boot(ARMCPU *cpu, error_report("could not load firmware '%s'", firmware_filename); exit(1); } + + add_event_log(info); } static void arm_setup_firmware_boot(ARMCPU *cpu, struct arm_boot_info *info, diff --git a/hw/arm/virt.c b/hw/arm/virt.c index 5247f53882..1e0f664af0 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -1808,6 +1808,11 @@ void virt_machine_done(Notifier *notifier, void *data) exit(1); } + if (vms->event_log) { + object_property_set_uint(vms->event_log, "load-addr", + vms->bootinfo.log_start, &error_fatal); + } + fw_cfg_add_extra_pci_roots(vms->bus, vms->fw_cfg); virt_acpi_setup(vms); @@ -2149,6 +2154,21 @@ static void virt_cpu_post_init(VirtMachineState *vms, MemoryRegion *sysmem) } } +static void create_measurement_log(VirtMachineState *vms) +{ + Error *err = NULL; + + vms->event_log = kvm_arm_rme_get_measurement_log(); + if (vms->event_log == NULL) { + return; + } + vms->bootinfo.log_size = object_property_get_uint(vms->event_log, + "max-size", &err); + if (err != NULL) { + error_report_err(err); + } +} + static void machvirt_init(MachineState *machine) { VirtMachineState *vms = VIRT_MACHINE(machine); @@ -2499,6 +2519,9 @@ static void machvirt_init(MachineState *machine) vms->fw_cfg, OBJECT(vms)); } + kvm_arm_rme_set_ipa_size(64 - clz64(vms->highest_gpa)); + create_measurement_log(vms); + vms->bootinfo.ram_size = machine->ram_size; vms->bootinfo.board_id = -1; vms->bootinfo.loader_start = vms->memmap[VIRT_MEM].base;