From: Sean Christopherson <seanjc@google.com>
To: "Pratik R. Sampat" <prsampat@amd.com>
Cc: linux-kernel@vger.kernel.org, x86@kernel.org,
kvm@vger.kernel.org, linux-crypto@vger.kernel.org,
linux-kselftest@vger.kernel.org, pbonzini@redhat.com,
thomas.lendacky@amd.com, tglx@linutronix.de, mingo@redhat.com,
bp@alien8.de, dave.hansen@linux.intel.com, shuah@kernel.org,
pgonda@google.com, ashish.kalra@amd.com, nikunj@amd.com,
pankaj.gupta@amd.com, michael.roth@amd.com, sraithal@amd.com
Subject: Re: [PATCH v6 6/9] KVM: selftests: Add library support for interacting with SNP
Date: Tue, 11 Feb 2025 18:12:24 -0800 [thread overview]
Message-ID: <Z6wDiOGjSElatLBd@google.com> (raw)
In-Reply-To: <20250203223205.36121-7-prsampat@amd.com>
On Mon, Feb 03, 2025, Pratik R. Sampat wrote:
> Extend the SEV library to include support for SNP ioctl() wrappers,
> which aid in launching and interacting with a SEV-SNP guest.
>
> Tested-by: Srikanth Aithal <sraithal@amd.com>
> Signed-off-by: Pratik R. Sampat <prsampat@amd.com>
> ---
> v5..v6:
>
> * Collected tags from Srikanth.
> ---
> tools/testing/selftests/kvm/include/x86/sev.h | 49 ++++++++++-
> tools/testing/selftests/kvm/lib/x86/sev.c | 82 +++++++++++++++++--
> 2 files changed, 125 insertions(+), 6 deletions(-)
>
> diff --git a/tools/testing/selftests/kvm/include/x86/sev.h b/tools/testing/selftests/kvm/include/x86/sev.h
> index faed91435963..fd5d5261e10e 100644
> --- a/tools/testing/selftests/kvm/include/x86/sev.h
> +++ b/tools/testing/selftests/kvm/include/x86/sev.h
> @@ -22,9 +22,20 @@ enum sev_guest_state {
> SEV_GUEST_STATE_RUNNING,
> };
>
> +/* Minimum firmware version required for the SEV-SNP support */
> +#define SNP_MIN_API_MAJOR 1
> +#define SNP_MIN_API_MINOR 51
Dead code. Selftests don't care about this.
> #define SEV_POLICY_NO_DBG (1UL << 0)
> #define SEV_POLICY_ES (1UL << 2)
>
> +#define SNP_POLICY_SMT (1ULL << 16)
> +#define SNP_POLICY_RSVD_MBO (1ULL << 17)
> +#define SNP_POLICY_DBG (1ULL << 19)
> +
> +#define SNP_FW_VER_MINOR(min) ((uint8_t)(min) << 0)
> +#define SNP_FW_VER_MAJOR(maj) ((uint8_t)(maj) << 8)
Also dead code.
> #define GHCB_MSR_TERM_REQ 0x100
>
> #define VMGEXIT() { __asm__ __volatile__("rep; vmmcall"); }
> @@ -36,13 +47,35 @@ bool is_sev_snp_vm(struct kvm_vm *vm);
> void sev_vm_launch(struct kvm_vm *vm, uint32_t policy);
> void sev_vm_launch_measure(struct kvm_vm *vm, uint8_t *measurement);
> void sev_vm_launch_finish(struct kvm_vm *vm);
> +void snp_vm_launch_start(struct kvm_vm *vm, uint64_t policy);
> +void snp_vm_launch_update(struct kvm_vm *vm);
> +void snp_vm_launch_finish(struct kvm_vm *vm);
>
> struct kvm_vm *vm_sev_create_with_one_vcpu(uint32_t type, void *guest_code,
> struct kvm_vcpu **cpu);
> -void vm_sev_launch(struct kvm_vm *vm, uint32_t policy, uint8_t *measurement);
> +void vm_sev_launch(struct kvm_vm *vm, uint64_t policy, uint8_t *measurement);
>
> kvm_static_assert(SEV_RET_SUCCESS == 0);
>
> +/*
> + * A SEV-SNP VM requires the policy reserved bit to always be set.
> + * The SMT policy bit is also required to be set based on SMT being
> + * available and active on the system.
> + */
> +static inline u64 snp_default_policy(void)
> +{
> + bool smt_active = false;
> + FILE *f;
> +
> + f = fopen("/sys/devices/system/cpu/smt/active", "r");
Please add a helper to query if SMT is enabled. I doubt there will ever be many
users of this, but it doesn't seem like something that should buried in SNP code.
Ha! smt_possible() in tools/testing/selftests/kvm/x86/hyperv_cpuid.c is already
guilty of burying a related helper, and it looks like it's a more robust version.
> + if (f) {
> + smt_active = fgetc(f) - '0';
> + fclose(f);
> + }
> +
> + return SNP_POLICY_RSVD_MBO | (smt_active ? SNP_POLICY_SMT : 0);
> +}
> +
> /*
> * The KVM_MEMORY_ENCRYPT_OP uAPI is utter garbage and takes an "unsigned long"
> * instead of a proper struct. The size of the parameter is embedded in the
> @@ -76,6 +109,7 @@ kvm_static_assert(SEV_RET_SUCCESS == 0);
>
> void sev_vm_init(struct kvm_vm *vm);
> void sev_es_vm_init(struct kvm_vm *vm);
> +void snp_vm_init(struct kvm_vm *vm);
>
> static inline void sev_register_encrypted_memory(struct kvm_vm *vm,
> struct userspace_mem_region *region)
> @@ -99,4 +133,17 @@ static inline void sev_launch_update_data(struct kvm_vm *vm, vm_paddr_t gpa,
> vm_sev_ioctl(vm, KVM_SEV_LAUNCH_UPDATE_DATA, &update_data);
> }
>
> +static inline void snp_launch_update_data(struct kvm_vm *vm, vm_paddr_t gpa,
> + uint64_t hva, uint64_t size, uint8_t type)
> +{
> + struct kvm_sev_snp_launch_update update_data = {
> + .uaddr = hva,
> + .gfn_start = gpa >> PAGE_SHIFT,
> + .len = size,
> + .type = type,
> + };
> +
> + vm_sev_ioctl(vm, KVM_SEV_SNP_LAUNCH_UPDATE, &update_data);
> +}
> +
> #endif /* SELFTEST_KVM_SEV_H */
> diff --git a/tools/testing/selftests/kvm/lib/x86/sev.c b/tools/testing/selftests/kvm/lib/x86/sev.c
> index 280ec42e281b..17d493e9907a 100644
> --- a/tools/testing/selftests/kvm/lib/x86/sev.c
> +++ b/tools/testing/selftests/kvm/lib/x86/sev.c
> @@ -31,7 +31,8 @@ bool is_sev_vm(struct kvm_vm *vm)
> * and find the first range, but that's correct because the condition
> * expression would cause us to quit the loop.
> */
> -static void encrypt_region(struct kvm_vm *vm, struct userspace_mem_region *region)
> +static void encrypt_region(struct kvm_vm *vm, struct userspace_mem_region *region,
> + uint8_t page_type)
> {
> const struct sparsebit *protected_phy_pages = region->protected_phy_pages;
> const vm_paddr_t gpa_base = region->region.guest_phys_addr;
> @@ -41,13 +42,35 @@ static void encrypt_region(struct kvm_vm *vm, struct userspace_mem_region *regio
> if (!sparsebit_any_set(protected_phy_pages))
> return;
>
> - sev_register_encrypted_memory(vm, region);
> + if (!is_sev_snp_vm(vm))
> + sev_register_encrypted_memory(vm, region);
>
> sparsebit_for_each_set_range(protected_phy_pages, i, j) {
> const uint64_t size = (j - i + 1) * vm->page_size;
> const uint64_t offset = (i - lowest_page_in_region) * vm->page_size;
>
> - sev_launch_update_data(vm, gpa_base + offset, size);
> + if (is_sev_snp_vm(vm)) {
Curly braces are unnecessary.
> + snp_launch_update_data(vm, gpa_base + offset,
> + (uint64_t)addr_gpa2hva(vm, gpa_base + offset),
> + size, page_type);
> + } else {
> + sev_launch_update_data(vm, gpa_base + offset, size);
> + }
> + }
> +}
> +
> +static void privatize_region(struct kvm_vm *vm, struct userspace_mem_region *region)
Can't this just be a param to encrypt_region() that also says "make it private"?
> +{
> + const struct sparsebit *protected_phy_pages = region->protected_phy_pages;
> + const vm_paddr_t gpa_base = region->region.guest_phys_addr;
> + const sparsebit_idx_t lowest_page_in_region = gpa_base >> vm->page_shift;
> + sparsebit_idx_t i, j;
> +
> + sparsebit_for_each_set_range(protected_phy_pages, i, j) {
> + const uint64_t size = (j - i + 1) * vm->page_size;
> + const uint64_t offset = (i - lowest_page_in_region) * vm->page_size;
> +
> + vm_mem_set_private(vm, gpa_base + offset, size);
> }
> }
>
> @@ -77,6 +100,14 @@ void sev_es_vm_init(struct kvm_vm *vm)
> }
> }
>
> +void snp_vm_init(struct kvm_vm *vm)
> +{
> + struct kvm_sev_init init = { 0 };
> +
> + assert(vm->type == KVM_X86_SNP_VM);
Use TEST_ASSERT(), or do nothing, don't use assert().
> + vm_sev_ioctl(vm, KVM_SEV_INIT2, &init);
> +}
> +
> void sev_vm_launch(struct kvm_vm *vm, uint32_t policy)
> {
> struct kvm_sev_launch_start launch_start = {
> @@ -93,7 +124,7 @@ void sev_vm_launch(struct kvm_vm *vm, uint32_t policy)
> TEST_ASSERT_EQ(status.state, SEV_GUEST_STATE_LAUNCH_UPDATE);
>
> hash_for_each(vm->regions.slot_hash, ctr, region, slot_node)
> - encrypt_region(vm, region);
> + encrypt_region(vm, region, 0);
Please add an enum/macro instead of open coding a literal '0'. I gotta assume
there's an appropriate name for page type '0'.
>
> if (policy & SEV_POLICY_ES)
> vm_sev_ioctl(vm, KVM_SEV_LAUNCH_UPDATE_VMSA, NULL);
next prev parent reply other threads:[~2025-02-12 2:12 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-02-03 22:31 [PATCH v6 0/9] Basic SEV-SNP Selftests Pratik R. Sampat
2025-02-03 22:31 ` [PATCH v6 1/9] KVM: SEV: Disable SEV-SNP on FW validation failure Pratik R. Sampat
2025-02-12 1:54 ` Sean Christopherson
2025-02-14 18:07 ` Pratik Rajesh Sampat
2025-02-03 22:31 ` [PATCH v6 2/9] KVM: SEV: Disable SEV on platform init failure Pratik R. Sampat
2025-02-12 1:58 ` Sean Christopherson
2025-02-14 18:09 ` Pratik Rajesh Sampat
2025-02-03 22:31 ` [PATCH v6 3/9] KVM: selftests: SEV-SNP test for KVM_SEV_INIT2 Pratik R. Sampat
2025-02-03 22:32 ` [PATCH v6 4/9] KVM: selftests: Add VMGEXIT helper Pratik R. Sampat
2025-02-12 1:59 ` Sean Christopherson
2025-02-14 18:09 ` Pratik Rajesh Sampat
2025-02-03 22:32 ` [PATCH v6 5/9] KVM: selftests: Introduce SEV VM type check Pratik R. Sampat
2025-02-03 22:32 ` [PATCH v6 6/9] KVM: selftests: Add library support for interacting with SNP Pratik R. Sampat
2025-02-12 2:12 ` Sean Christopherson [this message]
2025-02-14 18:12 ` Pratik Rajesh Sampat
2025-02-19 16:55 ` Sean Christopherson
2025-02-20 16:56 ` Pratik Rajesh Sampat
2025-02-03 22:32 ` [PATCH v6 7/9] KVM: selftests: Force GUEST_MEMFD flag for SNP VM type Pratik R. Sampat
2025-02-03 22:32 ` [PATCH v6 8/9] KVM: selftests: Abstractions for SEV to decouple policy from type Pratik R. Sampat
2025-02-03 22:32 ` [PATCH v6 9/9] KVM: selftests: Add a basic SEV-SNP smoke test Pratik R. Sampat
2025-02-12 2:31 ` Sean Christopherson
2025-02-14 18:14 ` Pratik Rajesh Sampat
2025-02-19 0:54 ` Sean Christopherson
2025-02-19 14:58 ` Pratik Rajesh Sampat
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=Z6wDiOGjSElatLBd@google.com \
--to=seanjc@google.com \
--cc=ashish.kalra@amd.com \
--cc=bp@alien8.de \
--cc=dave.hansen@linux.intel.com \
--cc=kvm@vger.kernel.org \
--cc=linux-crypto@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=michael.roth@amd.com \
--cc=mingo@redhat.com \
--cc=nikunj@amd.com \
--cc=pankaj.gupta@amd.com \
--cc=pbonzini@redhat.com \
--cc=pgonda@google.com \
--cc=prsampat@amd.com \
--cc=shuah@kernel.org \
--cc=sraithal@amd.com \
--cc=tglx@linutronix.de \
--cc=thomas.lendacky@amd.com \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.