Re: [PATCH v19 014/130] KVM: Add KVM vcpu ioctl to pre-populate guest memory

Isaku Yamahata
2024-03-08T21:01:17Z

On Thu, Mar 07, 2024 at 03:01:11PM +0800,
Yin Fengwei <fengwei.yin@intel.com> wrote:

> > diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
> > index 0349e1f241d1..2f0a8e28795e 100644
> > --- a/virt/kvm/kvm_main.c
> > +++ b/virt/kvm/kvm_main.c
> > @@ -4409,6 +4409,62 @@ static int kvm_vcpu_ioctl_get_stats_fd(struct kvm_vcpu *vcpu)
> > return fd;
> > }
> >
> > +__weak void kvm_arch_vcpu_pre_memory_mapping(struct kvm_vcpu *vcpu)
> > +{
> > +}
> > +
> > +__weak int kvm_arch_vcpu_memory_mapping(struct kvm_vcpu *vcpu,
> > + struct kvm_memory_mapping *mapping)
> > +{
> > + return -EOPNOTSUPP;
> > +}
> > +
> > +static int kvm_vcpu_memory_mapping(struct kvm_vcpu *vcpu,
> > + struct kvm_memory_mapping *mapping)
> > +{
> > + bool added = false;
> > + int idx, r = 0;
> > +
> > + /* flags isn't used yet. */
> > + if (mapping->flags)
> > + return -EINVAL;
> > +
> > + /* Sanity check */
> > + if (!IS_ALIGNED(mapping->source, PAGE_SIZE) ||
> > + !mapping->nr_pages ||
> > + mapping->nr_pages & GENMASK_ULL(63, 63 - PAGE_SHIFT) ||
> > + mapping->base_gfn + mapping->nr_pages <= mapping->base_gfn)
> I suppose !mapping->nr_pages can be deleted as this line can cover it.
> > + return -EINVAL;
> > +
> > + vcpu_load(vcpu);
> > + idx = srcu_read_lock(&vcpu->kvm->srcu);
> > + kvm_arch_vcpu_pre_memory_mapping(vcpu);
> > +
> > + while (mapping->nr_pages) {
> > + if (signal_pending(current)) {
> > + r = -ERESTARTSYS;
> > + break;
> > + }
> > +
> > + if (need_resched())
> > + cond_resched();
> > +
> > + r = kvm_arch_vcpu_memory_mapping(vcpu, mapping);
> > + if (r)
> > + break;
> > +
> > + added = true;
> > + }
> > +
> > + srcu_read_unlock(&vcpu->kvm->srcu, idx);
> > + vcpu_put(vcpu);
> > +
> > + if (added && mapping->nr_pages > 0)
> > + r = -EAGAIN;
> > +
> > + return r;
> > +}
> > +
> > static long kvm_vcpu_ioctl(struct file *filp,
> > unsigned int ioctl, unsigned long arg)
> > {
> > @@ -4610,6 +4666,17 @@ static long kvm_vcpu_ioctl(struct file *filp,
> > r = kvm_vcpu_ioctl_get_stats_fd(vcpu);
> > break;
> > }
> > + case KVM_MEMORY_MAPPING: {
> > + struct kvm_memory_mapping mapping;
> > +
> > + r = -EFAULT;
> > + if (copy_from_user(&mapping, argp, sizeof(mapping)))
> > + break;
> > + r = kvm_vcpu_memory_mapping(vcpu, &mapping);
> return value r should be checked before copy_to_user

That's intentional to tell the mapping is partially or fully processed
regardless that error happened or not.

>
>
> Regards
> Yin, Fengwei
>
> > + if (copy_to_user(argp, &mapping, sizeof(mapping)))
> > + r = -EFAULT;
> > + break;
> > + }
> > default:
> > r = kvm_arch_vcpu_ioctl(filp, ioctl, arg);
> > }
>

--
Isaku Yamahata <isaku.yamahata@intel.com>