From: Sean Christopherson <seanjc@google.com>
To: isaku.yamahata@intel.com
Cc: kvm@vger.kernel.org, linux-kernel@vger.kernel.org,
isaku.yamahata@gmail.com, Paolo Bonzini <pbonzini@redhat.com>,
erdemaktas@google.com, Sagi Shahar <sagis@google.com>,
David Matlack <dmatlack@google.com>,
Kai Huang <kai.huang@intel.com>,
Zhi Wang <zhi.wang.linux@gmail.com>,
chen.bo@intel.com, linux-coco@lists.linux.dev,
Chao Peng <chao.p.peng@linux.intel.com>,
Ackerley Tng <ackerleytng@google.com>,
Vishal Annapurve <vannapurve@google.com>,
Michael Roth <michael.roth@amd.com>,
Yuan Yao <yuan.yao@linux.intel.com>
Subject: Re: [RFC PATCH v3 08/11] KVM: Fix set_mem_attr ioctl when error case
Date: Thu, 13 Jul 2023 15:03:54 -0700 [thread overview]
Message-ID: <ZLB0ytO7y4NOLWpL@google.com> (raw)
In-Reply-To: <358fb191b3690a5cbc2c985d3ffc67224df11cf3.1687991811.git.isaku.yamahata@intel.com>
On Wed, Jun 28, 2023, isaku.yamahata@intel.com wrote:
> From: Isaku Yamahata <isaku.yamahata@intel.com>
>
> kvm_vm_ioctl_set_mem_attributes() discarded an error code of xa_err()
> unconditionally. If an error occurred at the beginning, return error.
>
> Fixes: 3779c214835b ("KVM: Introduce per-page memory attributes")
> Signed-off-by: Isaku Yamahata <isaku.yamahata@intel.com>
>
> ---
> Changes v2 -> v3:
> - Newly added
> ---
> virt/kvm/kvm_main.c | 12 ++++++++----
> 1 file changed, 8 insertions(+), 4 deletions(-)
>
> diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
> index 422d49634c56..fdef56f85174 100644
> --- a/virt/kvm/kvm_main.c
> +++ b/virt/kvm/kvm_main.c
> @@ -2423,6 +2423,7 @@ static int kvm_vm_ioctl_set_mem_attributes(struct kvm *kvm,
> gfn_t start, end;
> unsigned long i;
> void *entry;
> + int err = 0;
>
> /* flags is currently not used. */
> if (attrs->flags)
> @@ -2447,14 +2448,17 @@ static int kvm_vm_ioctl_set_mem_attributes(struct kvm *kvm,
> KVM_MMU_UNLOCK(kvm);
>
> for (i = start; i < end; i++) {
> - if (xa_err(xa_store(&kvm->mem_attr_array, i, entry,
> - GFP_KERNEL_ACCOUNT)))
> + err = xa_err(xa_store(&kvm->mem_attr_array, i, entry,
> + GFP_KERNEL_ACCOUNT));
> + if (err)
> break;
> }
>
> KVM_MMU_LOCK(kvm);
> - if (i > start)
> + if (i > start) {
> + err = 0;
> kvm_mem_attrs_changed(kvm, attrs->attributes, start, i);
> + }
> kvm_mmu_invalidate_end(kvm);
> KVM_MMU_UNLOCK(kvm);
>
> @@ -2463,7 +2467,7 @@ static int kvm_vm_ioctl_set_mem_attributes(struct kvm *kvm,
> attrs->address = i << PAGE_SHIFT;
> attrs->size = (end - i) << PAGE_SHIFT;
>
> - return 0;
> + return err;
Aha! Idea (stolen from commit afb2acb2e3a3 ("KVM: Fix vcpu_array[0] races")).
Rather than deal with a potential error partway through the updates, reserve all
xarray entries head of time. That way the ioctl() is all-or-nothing, e.g. KVM
doesn't need to update the address+size to capture progress, and userspace doesn't
have to retry (which is probably pointless anyways since failure to allocate an
xarray entry likely means the system/cgroup is under intense memory pressure).
Assuming it works (compile tested only), I'll squash this:
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 46fbb4e019a6..8cb972038dab 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -2278,7 +2278,7 @@ struct kvm_s390_zpci_op {
/* Available with KVM_CAP_MEMORY_ATTRIBUTES */
#define KVM_GET_SUPPORTED_MEMORY_ATTRIBUTES _IOR(KVMIO, 0xd2, __u64)
-#define KVM_SET_MEMORY_ATTRIBUTES _IOWR(KVMIO, 0xd3, struct kvm_memory_attributes)
+#define KVM_SET_MEMORY_ATTRIBUTES _IOW(KVMIO, 0xd3, struct kvm_memory_attributes)
struct kvm_memory_attributes {
__u64 address;
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index 9584491c0cd3..93e82e3f1e1f 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -2425,6 +2425,7 @@ static int kvm_vm_ioctl_set_mem_attributes(struct kvm *kvm,
gfn_t start, end;
unsigned long i;
void *entry;
+ int r;
/* flags is currently not used. */
if (attrs->flags)
@@ -2439,18 +2440,32 @@ static int kvm_vm_ioctl_set_mem_attributes(struct kvm *kvm,
start = attrs->address >> PAGE_SHIFT;
end = (attrs->address + attrs->size - 1 + PAGE_SIZE) >> PAGE_SHIFT;
+ if (WARN_ON_ONCE(start == end))
+ return -EINVAL;
+
entry = attrs->attributes ? xa_mk_value(attrs->attributes) : NULL;
mutex_lock(&kvm->slots_lock);
+ /*
+ * Reserve memory ahead of time to avoid having to deal with failures
+ * partway through setting the new attributes.
+ */
+ for (i = start; i < end; i++) {
+ r = xa_reserve(&kvm->mem_attr_array, i, GFP_KERNEL_ACCOUNT);
+ if (r)
+ goto out_unlock;
+ }
+
KVM_MMU_LOCK(kvm);
kvm_mmu_invalidate_begin(kvm);
kvm_mmu_invalidate_range_add(kvm, start, end);
KVM_MMU_UNLOCK(kvm);
for (i = start; i < end; i++) {
- if (xa_err(xa_store(&kvm->mem_attr_array, i, entry,
- GFP_KERNEL_ACCOUNT)))
+ r = xa_err(xa_store(&kvm->mem_attr_array, i, entry,
+ GFP_KERNEL_ACCOUNT));
+ if (KVM_BUG_ON(r, kvm))
break;
}
@@ -2460,12 +2475,10 @@ static int kvm_vm_ioctl_set_mem_attributes(struct kvm *kvm,
kvm_mmu_invalidate_end(kvm);
KVM_MMU_UNLOCK(kvm);
+out_unlock:
mutex_unlock(&kvm->slots_lock);
- attrs->address = i << PAGE_SHIFT;
- attrs->size = (end - i) << PAGE_SHIFT;
-
- return 0;
+ return r;
}
#endif /* CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES */
@@ -5078,9 +5091,6 @@ static long kvm_vm_ioctl(struct file *filp,
goto out;
r = kvm_vm_ioctl_set_mem_attributes(kvm, &attrs);
-
- if (!r && copy_to_user(argp, &attrs, sizeof(attrs)))
- r = -EFAULT;
break;
}
#endif /* CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES */
next prev parent reply other threads:[~2023-07-13 22:03 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-06-28 22:42 [RFC PATCH v3 00/11] KVM: guest memory: Misc enhacnement isaku.yamahata
2023-06-28 22:43 ` [RFC PATCH v3 01/11] KVM: selftests: Fix test_add_overlapping_private_memory_regions() isaku.yamahata
2023-06-28 22:43 ` [RFC PATCH v3 02/11] KVM: selftests: Fix guest_memfd() isaku.yamahata
2023-06-28 22:43 ` [RFC PATCH v3 03/11] KVM: selftests: x86: typo in private_mem_conversions_test.c isaku.yamahata
2023-06-28 22:43 ` [RFC PATCH v3 04/11] KVM: x86: Add is_vm_type_supported callback isaku.yamahata
2023-06-28 22:43 ` [RFC PATCH v3 05/11] KVM: x86/mmu: Pass around full 64-bit error code for the KVM page fault isaku.yamahata
2023-06-28 22:43 ` [RFC PATCH v3 06/11] KVM: x86: Introduce PFERR_GUEST_ENC_MASK to indicate fault is private isaku.yamahata
2023-06-28 22:43 ` [RFC PATCH v3 07/11] KVM: x86: Export the kvm_zap_gfn_range() for the SNP use isaku.yamahata
2023-06-28 22:43 ` [RFC PATCH v3 08/11] KVM: Fix set_mem_attr ioctl when error case isaku.yamahata
2023-07-13 22:03 ` Sean Christopherson [this message]
2023-07-14 8:57 ` Zhi Wang
2023-07-14 22:35 ` Sean Christopherson
2023-06-28 22:43 ` [RFC PATCH v3 09/11] KVM: Add new members to struct kvm_gfn_range to operate on isaku.yamahata
2023-07-13 22:10 ` Sean Christopherson
2023-07-15 4:30 ` Yu Zhao
2023-06-28 22:43 ` [RFC PATCH v3 10/11] KVM: x86: Add gmem hook for initializing private memory isaku.yamahata
2023-06-28 22:43 ` [RFC PATCH v3 11/11] KVM: x86: Add gmem hook for invalidating " isaku.yamahata
2023-07-19 14:20 ` [RFC PATCH v3 00/11] KVM: guest memory: Misc enhacnement Sean Christopherson
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=ZLB0ytO7y4NOLWpL@google.com \
--to=seanjc@google.com \
--cc=ackerleytng@google.com \
--cc=chao.p.peng@linux.intel.com \
--cc=chen.bo@intel.com \
--cc=dmatlack@google.com \
--cc=erdemaktas@google.com \
--cc=isaku.yamahata@gmail.com \
--cc=isaku.yamahata@intel.com \
--cc=kai.huang@intel.com \
--cc=kvm@vger.kernel.org \
--cc=linux-coco@lists.linux.dev \
--cc=linux-kernel@vger.kernel.org \
--cc=michael.roth@amd.com \
--cc=pbonzini@redhat.com \
--cc=sagis@google.com \
--cc=vannapurve@google.com \
--cc=yuan.yao@linux.intel.com \
--cc=zhi.wang.linux@gmail.com \
/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.