Received: by 2002:a05:6359:c8b:b0:c7:702f:21d4 with SMTP id go11csp903055rwb; Wed, 28 Sep 2022 10:27:45 -0700 (PDT) X-Google-Smtp-Source: AMsMyM4MUACazJXegUoN59iDNfar3YC26aqhGV9Rw1boFRqwa14lk/ua3mTEAYdoZmX6lvPHHxtH X-Received: by 2002:a17:902:bf08:b0:178:90fb:8cda with SMTP id bi8-20020a170902bf0800b0017890fb8cdamr838751plb.9.1664386064747; Wed, 28 Sep 2022 10:27:44 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1664386064; cv=none; d=google.com; s=arc-20160816; b=VYY+me33SyHMPialv1S7VJpeFJ0FjGhNwjiKV51eD9oNynnHxo3rr2QjMoerCIVFLS usO9RA1w8Hx4XAUOWFRbYSXsb7KUQkIGLXTGv3u/iAe72Pgk60zns0gWwOZHMXIm7Pnt IHkIFgr7Ro7ILy+xbU6Dqd9nYzrMt4HbRyN14y1Y7+lurSaS6QO1QJdKO/EWnIFEhO+i hFRIUqK0qvZ6PpXhBbjGLuPKQ9uhbco5JfWVfo+fR6umoFMPGVuLi1IiUgjBPYuc8dwF ++dr7l7sQ1MFE62v5T8wBYoe9lvFXIYfGXrTkBa1W6v8dvY+YJG2bUpCMcNjz1+VNfI/ XkEQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:in-reply-to:subject :from:references:cc:to:content-language:user-agent:mime-version:date :message-id:dkim-signature; bh=bP9+xy9pEpEEZfRNIBincGMZRHmli7unEWEFcnvOvfI=; b=ueflY3bDQC9YvrtwQ9QB/B67NssnEn6SNQaTIaN8DfQzOKl0zlsJupyxuttlplHLCR F8cpdfZ6NGVmliLqyMN6LlrkTqT20Fw+mTTpXnINPdvwhrE8IT1tgb/dcYEo+OLvAXQ/ 5xnK561Jb3Qjkk7JexMc9vxEkFB8I+5UU80GS62rkgn3zGo5WSl8vyvQBdMKGizx0Vb7 l9flT84XF5+AiULvpJnEr2zz5UqpxLBrh4XWBY1LxuTrD/Z0JbdGWDxjJCz/44Ll8Tp8 6hsXGint5EyjhfoXTmr0RVz2FbfDo1Ei68EP7t7uM/rvbWsrW3JDiav1mwcQM6wubFLj 4GKA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=CWC8gTNx; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id k11-20020a170902ba8b00b0017828d3c263si3184410pls.192.2022.09.28.10.27.32; Wed, 28 Sep 2022 10:27:44 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=CWC8gTNx; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234290AbiI1RMH (ORCPT + 99 others); Wed, 28 Sep 2022 13:12:07 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:32866 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234331AbiI1RMG (ORCPT ); Wed, 28 Sep 2022 13:12:06 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4FE64EBBFB for ; Wed, 28 Sep 2022 10:12:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1664385124; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=bP9+xy9pEpEEZfRNIBincGMZRHmli7unEWEFcnvOvfI=; b=CWC8gTNxlpkS2nYfNja7SCV5oCroBb6d07jEZNXBT8I1vDKLa3d92cNDMoZzNwR1H3Gr7v wOZN8CkcTuJK2tejKHK8EoSrQK2+009AVe6KcS8D1NAla2Iu/M700DT2aaQFHTRNeW+xO9 i5C8IVoiLiGKehTX3zH/EXeRrb22FlM= Received: from mail-ed1-f72.google.com (mail-ed1-f72.google.com [209.85.208.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_128_GCM_SHA256) id us-mta-396-BY4MH5TEN-yeTreJRMnSoQ-1; Wed, 28 Sep 2022 13:12:03 -0400 X-MC-Unique: BY4MH5TEN-yeTreJRMnSoQ-1 Received: by mail-ed1-f72.google.com with SMTP id y1-20020a056402358100b00451b144e23eso10706776edc.18 for ; Wed, 28 Sep 2022 10:12:03 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:in-reply-to:subject:from:references:cc:to :content-language:user-agent:mime-version:date:message-id :x-gm-message-state:from:to:cc:subject:date; bh=bP9+xy9pEpEEZfRNIBincGMZRHmli7unEWEFcnvOvfI=; b=ownrxPhYSDibN25AjI3VMW7g+wSLkMSxhqlT3HRK2WLoIGBGb0obwobVO44cO7CUCo 03MEKmvUNq1gW25fuOfaByODQazSoCh/qFX2cio+BeyTZYPBYBBPgwh1q6HY4Srgdyya ztn+q6yVtCSWiJu9jTtuj9AipqFs2LEreyZyg6aR2ZsoJAcYGe9E29GekHxvzsxuFfSs XGM5IyJtLrdPisnjp7b9+klt7BDYtlYzTOO8p1GAlumxBzKDD1hvTLHt8/ysbFhwJQF4 eYeI7f0iH4PT9TMLazK9Dqtlvax0L+6Rp+YOh8tXOVqHJ8BGvUGbzelETYqYOpAgyOYk g3BQ== X-Gm-Message-State: ACrzQf2I+lXT8aejGdEWfR8F7+RIqz51+buDnWjrBUzZRki5QcPTkBjw 8gbQOBgv+bLl5cTjOA/fga3Is13BLJVAnvi8is2vP/64+SmvSVbovTZ0hjW0+VTRc1Ai7txq7U5 DEcgpxC4+zYcsWwqNjKnblouA X-Received: by 2002:a17:906:5d16:b0:787:a9ee:3c9c with SMTP id g22-20020a1709065d1600b00787a9ee3c9cmr1151650ejt.467.1664385121712; Wed, 28 Sep 2022 10:12:01 -0700 (PDT) X-Received: by 2002:a17:906:5d16:b0:787:a9ee:3c9c with SMTP id g22-20020a1709065d1600b00787a9ee3c9cmr1151621ejt.467.1664385121427; Wed, 28 Sep 2022 10:12:01 -0700 (PDT) Received: from ?IPV6:2001:b07:6468:f312:2f4b:62da:3159:e077? ([2001:b07:6468:f312:2f4b:62da:3159:e077]) by smtp.googlemail.com with ESMTPSA id d8-20020a170906304800b0078167cb4536sm2642428ejd.118.2022.09.28.10.11.59 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 28 Sep 2022 10:12:00 -0700 (PDT) Message-ID: Date: Wed, 28 Sep 2022 19:11:59 +0200 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.2.1 Content-Language: en-US To: Emanuele Giuseppe Esposito , kvm@vger.kernel.org Cc: Sean Christopherson , Vitaly Kuznetsov , Wanpeng Li , Jim Mattson , Joerg Roedel , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , David Hildenbrand , Maxim Levitsky , x86@kernel.org, "H. Peter Anvin" , linux-kernel@vger.kernel.org References: <20220909104506.738478-1-eesposit@redhat.com> <20220909104506.738478-6-eesposit@redhat.com> From: Paolo Bonzini Subject: Re: [RFC PATCH 5/9] kvm_main.c: split __kvm_set_memory_region logic in kvm_check_mem and kvm_prepare_batch In-Reply-To: <20220909104506.738478-6-eesposit@redhat.com> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-4.5 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,NICE_REPLY_A, RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_NONE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 9/9/22 12:45, Emanuele Giuseppe Esposito wrote: > Just a function split. No functional change intended, > except for the fact that kvm_prepare_batch() does not > immediately call kvm_set_memslot() if batch->change is > KVM_MR_DELETE, but delegates the caller (__kvm_set_memory_region). > > Signed-off-by: Emanuele Giuseppe Esposito > --- > virt/kvm/kvm_main.c | 120 +++++++++++++++++++++++++++++--------------- > 1 file changed, 79 insertions(+), 41 deletions(-) > > diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c > index 17f07546d591..9d917af30593 100644 > --- a/virt/kvm/kvm_main.c > +++ b/virt/kvm/kvm_main.c > @@ -1927,19 +1927,9 @@ static bool kvm_check_memslot_overlap(struct kvm_memslots *slots, int id, > return false; > } > > -/* > - * Allocate some memory and give it an address in the guest physical address > - * space. > - * > - * Discontiguous memory is allowed, mostly for framebuffers. > - * This function takes also care of initializing batch->new/old/invalid/change > - * fields. > - * > - * Must be called holding kvm->slots_lock for write. > - */ > -int __kvm_set_memory_region(struct kvm *kvm, > - const struct kvm_userspace_memory_region *mem, > - struct kvm_internal_memory_region_list *batch) > +static int kvm_prepare_batch(struct kvm *kvm, > + const struct kvm_userspace_memory_region *mem, > + struct kvm_internal_memory_region_list *batch) > { > struct kvm_memory_slot *old, *new; > struct kvm_memslots *slots; > @@ -1947,34 +1937,10 @@ int __kvm_set_memory_region(struct kvm *kvm, > unsigned long npages; > gfn_t base_gfn; > int as_id, id; > - int r; > - > - r = check_memory_region_flags(mem); > - if (r) > - return r; > > as_id = mem->slot >> 16; > id = (u16)mem->slot; > > - /* General sanity checks */ > - if ((mem->memory_size & (PAGE_SIZE - 1)) || > - (mem->memory_size != (unsigned long)mem->memory_size)) > - return -EINVAL; > - if (mem->guest_phys_addr & (PAGE_SIZE - 1)) > - return -EINVAL; > - /* We can read the guest memory with __xxx_user() later on. */ > - if ((mem->userspace_addr & (PAGE_SIZE - 1)) || > - (mem->userspace_addr != untagged_addr(mem->userspace_addr)) || > - !access_ok((void __user *)(unsigned long)mem->userspace_addr, > - mem->memory_size)) > - return -EINVAL; > - if (as_id >= KVM_ADDRESS_SPACE_NUM || id >= KVM_MEM_SLOTS_NUM) > - return -EINVAL; > - if (mem->guest_phys_addr + mem->memory_size < mem->guest_phys_addr) > - return -EINVAL; > - if ((mem->memory_size >> PAGE_SHIFT) > KVM_MEM_MAX_NR_PAGES) > - return -EINVAL; > - > slots = __kvm_memslots(kvm, as_id); > > /* > @@ -1993,7 +1959,7 @@ int __kvm_set_memory_region(struct kvm *kvm, > > batch->change = KVM_MR_DELETE; > batch->new = NULL; > - return kvm_set_memslot(kvm, batch); > + return 0; > } > > base_gfn = (mem->guest_phys_addr >> PAGE_SHIFT); > @@ -2020,7 +1986,7 @@ int __kvm_set_memory_region(struct kvm *kvm, > else if (mem->flags != old->flags) > change = KVM_MR_FLAGS_ONLY; > else /* Nothing to change. */ > - return 0; > + return 1; > } > > if ((change == KVM_MR_CREATE || change == KVM_MR_MOVE) && > @@ -2041,12 +2007,81 @@ int __kvm_set_memory_region(struct kvm *kvm, > > batch->new = new; > batch->change = change; > + return 0; > +} > + > +static int kvm_check_mem(const struct kvm_userspace_memory_region *mem) > +{ > + int as_id, id; > + > + as_id = mem->slot >> 16; > + id = (u16)mem->slot; > + > + /* General sanity checks */ > + if ((mem->memory_size & (PAGE_SIZE - 1)) || > + (mem->memory_size != (unsigned long)mem->memory_size)) > + return -EINVAL; > + if (mem->guest_phys_addr & (PAGE_SIZE - 1)) > + return -EINVAL; > + /* We can read the guest memory with __xxx_user() later on. */ > + if ((mem->userspace_addr & (PAGE_SIZE - 1)) || > + (mem->userspace_addr != untagged_addr(mem->userspace_addr)) || > + !access_ok((void __user *)(unsigned long)mem->userspace_addr, > + mem->memory_size)) > + return -EINVAL; > + if (as_id >= KVM_ADDRESS_SPACE_NUM || id >= KVM_MEM_SLOTS_NUM) > + return -EINVAL; > + if (mem->guest_phys_addr + mem->memory_size < mem->guest_phys_addr) > + return -EINVAL; > + if ((mem->memory_size >> PAGE_SHIFT) > KVM_MEM_MAX_NR_PAGES) > + return -EINVAL; > + > + return 0; > +} > + > +static int kvm_check_memory_region(struct kvm *kvm, > + const struct kvm_userspace_memory_region *mem, > + struct kvm_internal_memory_region_list *batch) > +{ > + int r; > + > + r = check_memory_region_flags(mem); > + if (r) > + return r; > > - r = kvm_set_memslot(kvm, batch); > + r = kvm_check_mem(mem); > if (r) > - kfree(new); > + return r; > + > + r = kvm_prepare_batch(kvm, mem, batch); > + if (r && batch->new) > + kfree(batch->new); > + > return r; > } > + > +/* > + * Allocate some memory and give it an address in the guest physical address > + * space. > + * > + * Discontiguous memory is allowed, mostly for framebuffers. > + * This function takes also care of initializing batch->new/old/invalid/change > + * fields. > + * > + * Must be called holding kvm->slots_lock for write. > + */ > +int __kvm_set_memory_region(struct kvm *kvm, > + const struct kvm_userspace_memory_region *mem, > + struct kvm_internal_memory_region_list *batch) > +{ > + int r; > + > + r = kvm_check_memory_region(kvm, mem, batch); > + if (r) > + return r; > + > + return kvm_set_memslot(kvm, batch); > +} > EXPORT_SYMBOL_GPL(__kvm_set_memory_region); > > static int kvm_set_memory_region(struct kvm *kvm, > @@ -2061,6 +2096,9 @@ static int kvm_set_memory_region(struct kvm *kvm, > mutex_lock(&kvm->slots_lock); > r = __kvm_set_memory_region(kvm, mem, batch); > mutex_unlock(&kvm->slots_lock); > + /* r == 1 means empty request, nothing to do but no error */ > + if (r == 1) > + r = 0; This is weird... I think you have the order of the split slightly messed up. Doing this check earlier, roughly at the same time as the introduction of the new struct, is probably clearer. After having reviewed more of the code, I do think you should disaggregate __kvm_set_memory_region() in separate functions (check, build entry, prepare, commit) completely. kvm_set_memory_region() calls them and __kvm_set_memory_region() disappears completely. Paolo > return r; > } >