[PATCH RFC v2 21/50] samples/kvm: Remove donate, reclaim, and move operations from sample provider
From: Ackerley Tng via B4 Relay
Date: Thu Oct 22 2026 - 19:40:10 EST
From: Ackerley Tng <ackerleytng@xxxxxxxxxx>
Remove the MPS_MOVE, MPS_DONATE, and MPS_RECLAIM ioctls from the sample
memory provider.
These operations manage dynamic ownership transfers and returning memory
to the root pool, which adds complexity that is not needed for the core
interface design.
Signed-off-by: Ackerley Tng <ackerleytng@xxxxxxxxxx>
---
samples/kvm/mem_provider_sample.c | 86 ---------------------------------------
samples/kvm/mem_provider_sample.h | 35 ----------------
2 files changed, 121 deletions(-)
diff --git a/samples/kvm/mem_provider_sample.c b/samples/kvm/mem_provider_sample.c
index 8180959ab78ff..5afc433dce6e8 100644
--- a/samples/kvm/mem_provider_sample.c
+++ b/samples/kvm/mem_provider_sample.c
@@ -674,86 +674,6 @@ static bool mps_child_owns(struct mps_info *info, unsigned long first,
find_next_zero_bit(info->owned, e, s) >= e;
}
-static long mps_ctl_move(void __user *uarg)
-{
- struct mps_move mv;
- struct mps_info *src, *dst;
- unsigned long first, last;
- struct file *sf, *df;
- long ret;
-
- if (copy_from_user(&mv, uarg, sizeof(mv)))
- return -EFAULT;
- sf = mps_get_child(mv.src_fd, &src);
- if (IS_ERR(sf))
- return PTR_ERR(sf);
- df = mps_get_child(mv.dst_fd, &dst);
- if (IS_ERR(df)) {
- fput(sf);
- return PTR_ERR(df);
- }
-
- mutex_lock(&mps_root.lock);
- ret = mps_root_range(mv.offset, mv.len, &first, &last);
- if (ret)
- goto out;
- if (src == dst || !mps_child_owns(src, first, last) ||
- !mps_child_covers(dst, first, last)) {
- ret = -EINVAL;
- goto out;
- }
- /* Revoke from the source before the destination gets the pages. */
- mps_child_lose(src, first, last);
- mps_child_gain(dst, first, last);
-out:
- mutex_unlock(&mps_root.lock);
- fput(df);
- fput(sf);
- return ret;
-}
-
-static long mps_ctl_donate(void __user *uarg, bool reclaim)
-{
- struct mps_donate d;
- unsigned long first, last;
- struct mps_info *info;
- struct file *file;
- long ret;
-
- if (copy_from_user(&d, uarg, sizeof(d)))
- return -EFAULT;
- if (d.pad)
- return -EINVAL;
- file = mps_get_child(d.fd, &info);
- if (IS_ERR(file))
- return PTR_ERR(file);
-
- mutex_lock(&mps_root.lock);
- ret = mps_root_range(d.offset, d.len, &first, &last);
- if (ret)
- goto out;
- if (!reclaim) {
- if (!mps_child_owns(info, first, last)) {
- ret = -EINVAL;
- goto out;
- }
- mps_child_lose(info, first, last);
- bitmap_set(mps_root.donated, first, last - first);
- } else {
- if (!mps_child_covers(info, first, last) ||
- find_next_zero_bit(mps_root.donated, last, first) < last) {
- ret = -EINVAL;
- goto out;
- }
- bitmap_clear(mps_root.donated, first, last - first);
- mps_child_gain(info, first, last);
- }
-out:
- mutex_unlock(&mps_root.lock);
- fput(file);
- return ret;
-}
-
/*
* CTL_SET_READONLY and CTL_SET_PRESENT change a child's pages, by the owner on
* the control device. A VMM that holds the child fd cannot, so it cannot undo
@@ -795,12 +715,6 @@ static long mps_ctl_ioctl(struct file *file, unsigned int cmd,
return mps_ctl_setup(uarg);
case MPS_NEW_CHILD:
return mps_ctl_new_child(uarg);
- case MPS_MOVE:
- return mps_ctl_move(uarg);
- case MPS_DONATE:
- return mps_ctl_donate(uarg, false);
- case MPS_RECLAIM:
- return mps_ctl_donate(uarg, true);
case MPS_CTL_SET_READONLY:
return mps_ctl_set_range(uarg, true);
case MPS_CTL_SET_PRESENT:
diff --git a/samples/kvm/mem_provider_sample.h b/samples/kvm/mem_provider_sample.h
index 0e036d1c76a45..acff5785099b5 100644
--- a/samples/kvm/mem_provider_sample.h
+++ b/samples/kvm/mem_provider_sample.h
@@ -68,41 +68,6 @@ struct mps_new_child {
#define MPS_NEW_CHILD \
_IOW(MPS_IOCTL_BASE, 5, struct mps_new_child)
-/*
- * ioctl on /dev/mem_provider_sample: move [@offset, @offset + @len) of the root
- * from child @src_fd to child @dst_fd. @src_fd must have every page of the
- * range, and the range must be inside @dst_fd's. The pages are revoked from
- * the source before the destination gets them, so the consumers of the two
- * children never map them at the same time.
- */
-struct mps_move {
- __s32 src_fd;
- __s32 dst_fd;
- __u64 offset; /* bytes into the root, page aligned */
- __u64 len; /* bytes, page aligned */
-};
-
-#define MPS_MOVE \
- _IOW(MPS_IOCTL_BASE, 6, struct mps_move)
-
-/*
- * ioctls on /dev/mem_provider_sample: DONATE takes [@offset, @offset + @len) of
- * the root from child @fd, which must have all of it, and keeps it at the
- * root. RECLAIM gives a donated range to child @fd, whose range must
- * contain it. The sample does not scrub the pages.
- */
-struct mps_donate {
- __s32 fd;
- __u32 pad;
- __u64 offset; /* bytes into the root, page aligned */
- __u64 len; /* bytes, page aligned */
-};
-
-#define MPS_DONATE \
- _IOW(MPS_IOCTL_BASE, 7, struct mps_donate)
-#define MPS_RECLAIM \
- _IOW(MPS_IOCTL_BASE, 8, struct mps_donate)
-
/* ioctl on a child fd: read the child's state, for tests. */
struct mps_stats {
__u64 region_offset; /* the child's range in the root */
--
2.56.0.257.gf7497c7d27-goog