If restricted guest memory is enabled, use the new extended guest memory region interface to pass the guest memory to kvm using the restricted file descriptor. In the future, pKVM will require this, and the successor of patch will instead force the use of restricted guest memory for pKVM (and other potential environments) that require restricted memory. Signed-off-by: Fuad Tabba <tabba@xxxxxxxxxx> --- kvm.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 49 insertions(+), 5 deletions(-) diff --git a/kvm.c b/kvm.c index fc0bfc4..bde6708 100644 --- a/kvm.c +++ b/kvm.c @@ -214,6 +214,41 @@ static int set_user_memory_region(int vm_fd, u32 slot, u32 flags, return ret; } +static int set_user_memory_region_ext(int vm_fd, u32 slot, u32 flags, + u64 guest_phys, u64 size, + u64 userspace_addr, u32 fd, u64 offset) +{ + int ret = 0; + struct kvm_enc_region range; + struct kvm_userspace_memory_region_ext mem = { + .region = { + .slot = slot, + .flags = flags, + .guest_phys_addr = guest_phys, + .memory_size = size, + .userspace_addr = 0, + }, + .restricted_fd = fd, + .restricted_offset = offset, + }; + + ret = ioctl(vm_fd, KVM_SET_USER_MEMORY_REGION, &mem); + if (ret < 0) { + ret = -errno; + goto out; + } + + /* Inform KVM that the region is protected. */ + range.addr = guest_phys; + range.size = size; + ret = ioctl(vm_fd, KVM_MEMORY_ENCRYPT_REG_REGION, &range); + if (ret) + ret = -errno; + +out: + return ret; +} + int kvm__destroy_mem(struct kvm *kvm, u64 guest_phys, u64 size, void *userspace_addr) { @@ -240,8 +275,13 @@ int kvm__destroy_mem(struct kvm *kvm, u64 guest_phys, u64 size, goto out; } - ret = set_user_memory_region(kvm->vm_fd, bank->slot, 0, guest_phys, 0, - (u64) userspace_addr); + if (kvm->cfg.restricted_mem) + ret = set_user_memory_region_ext(kvm->vm_fd, bank->slot, + KVM_MEM_PRIVATE, guest_phys, 0, (u64) userspace_addr, + 0, 0); + else + ret = set_user_memory_region(kvm->vm_fd, bank->slot, 0, + guest_phys, 0, (u64) userspace_addr); if (ret < 0) goto out; @@ -339,9 +379,13 @@ int kvm__register_mem(struct kvm *kvm, u64 guest_phys, u64 size, flags |= KVM_MEM_READONLY; if (type != KVM_MEM_TYPE_RESERVED) { - ret = set_user_memory_region(kvm->vm_fd, slot, flags, - guest_phys, size, - (u64) userspace_addr); + if (kvm->cfg.restricted_mem) + ret = set_user_memory_region_ext(kvm->vm_fd, slot, + flags | KVM_MEM_PRIVATE, guest_phys, size, + (u64) userspace_addr, memfd, offset); + else + ret = set_user_memory_region(kvm->vm_fd, slot, flags, + guest_phys, size, (u64) userspace_addr); if (ret < 0) goto out; } -- 2.39.0.rc0.267.gcb52ba06e7-goog