[POC PATCH 6/6] KVM: selftests: Test content modes ZERO and PRESERVE for SNP

Ackerley Tng
2026-03-26T23:37:10Z

.../selftests/kvm/x86/sev_smoke_test.c | 47 +++++++++++++++++--
1 file changed, 44 insertions(+), 3 deletions(-)

diff --git a/tools/testing/selftests/kvm/x86/sev_smoke_test.c b/tools/testing/selftests/kvm/x86/sev_smoke_test.c
index c40c359f78901..b076e0afc3077 100644
--- a/tools/testing/selftests/kvm/x86/sev_smoke_test.c
+++ b/tools/testing/selftests/kvm/x86/sev_smoke_test.c
@@ -365,7 +365,26 @@ static void guest_code_conversion(u8 *test_shared_gva, u8 *test_private_gva, u64
vmgexit();
}

-static void test_conversion(uint64_t policy)
+static void vm_set_memory_attributes_expect_error(struct kvm_vm *vm, u64 gpa,
+ size_t size, u64 attributes,
+ u64 flags, int expected_errno)
+{
+ loff_t error_offset = -1;
+ size_t len_ignored;
+ loff_t offset;
+ int gmem_fd;
+ int ret;
+
+ gmem_fd = kvm_gpa_to_guest_memfd(vm, gpa, &offset, &len_ignored);
+ ret = __gmem_set_memory_attributes(gmem_fd, offset, size, attributes,
+ &error_offset, flags);
+
+ TEST_ASSERT_EQ(ret, -1);
+ TEST_ASSERT_EQ(offset, error_offset);
+ TEST_ASSERT_EQ(errno, expected_errno);
+}
+
+static void test_conversion(uint64_t policy, u64 content_mode)
{
vm_vaddr_t test_private_gva;
vm_vaddr_t test_shared_gva;
@@ -409,6 +428,21 @@ static void test_conversion(uint64_t policy)
TEST_ASSERT_EQ(vcpu->run->hypercall.args[1], 1);
TEST_ASSERT_EQ(vcpu->run->hypercall.args[2], KVM_MAP_GPA_RANGE_ENCRYPTED | KVM_MAP_GPA_RANGE_PAGE_SZ_4K);

+ /* ZERO when setting memory attributes to private is always not supported. */
+ vm_set_memory_attributes_expect_error(vm, test_gpa, PAGE_SIZE,
+ KVM_MEMORY_ATTRIBUTE_PRIVATE,
+ KVM_SET_MEMORY_ATTRIBUTES2_ZERO,
+ EOPNOTSUPP);
+
+ /* PRESERVE is not supported for SNP. */
+ vm_set_memory_attributes_expect_error(vm, test_gpa, PAGE_SIZE, 0,
+ KVM_SET_MEMORY_ATTRIBUTES2_PRESERVE,
+ EOPNOTSUPP);
+ vm_set_memory_attributes_expect_error(vm, test_gpa, PAGE_SIZE,
+ KVM_MEMORY_ATTRIBUTE_PRIVATE,
+ KVM_SET_MEMORY_ATTRIBUTES2_PRESERVE,
+ EOPNOTSUPP);
+
vm_mem_set_private(vm, test_gpa, PAGE_SIZE, KVM_SET_MEMORY_ATTRIBUTES2_MODE_UNSPECIFIED);

vcpu_run(vcpu);
@@ -419,7 +453,12 @@ static void test_conversion(uint64_t policy)
TEST_ASSERT_EQ(vcpu->run->hypercall.args[1], 1);
TEST_ASSERT_EQ(vcpu->run->hypercall.args[2], KVM_MAP_GPA_RANGE_DECRYPTED | KVM_MAP_GPA_RANGE_PAGE_SZ_4K);

- vm_mem_set_shared(vm, test_gpa, PAGE_SIZE, KVM_SET_MEMORY_ATTRIBUTES2_MODE_UNSPECIFIED);
+ vm_mem_set_shared(vm, test_gpa, PAGE_SIZE, content_mode);
+
+ if (content_mode == KVM_SET_MEMORY_ATTRIBUTES2_ZERO)
+ TEST_ASSERT_EQ(READ_ONCE(*(u8 *)test_hva), 0);
+ else
+ fprintf(stderr, "test_hva contents = %x\n", READ_ONCE(*(u8 *)test_hva));

vcpu_run(vcpu);

@@ -441,7 +480,9 @@ int main(int argc, char *argv[])
// test_sev_smoke(guest_sev_es_code, KVM_X86_SEV_ES_VM, SEV_POLICY_ES);

if (kvm_cpu_has(X86_FEATURE_SEV_SNP)) {
- test_conversion(snp_default_policy());
+ test_conversion(snp_default_policy(), KVM_SET_MEMORY_ATTRIBUTES2_MODE_UNSPECIFIED);
+ test_conversion(snp_default_policy(), KVM_SET_MEMORY_ATTRIBUTES2_ZERO);
+
// test_sev_smoke(guest_snp_code, KVM_X86_SNP_VM, snp_default_policy());
}

--
2.53.0.1018.g2bb0e51243-goog