On Mon, Apr 22, 2024 at 12:58 PM Xu Yilun <yilun.xu@xxxxxxxxxxxxxxx> wrote: > > In some cases, it is necessary to defer the preparation of the pages to > > handle things like in-place encryption of initial guest memory payloads > > before marking these pages as 'private'/'guest-owned'. Add an argument > > (always true for now) to kvm_gmem_get_folio() that allows for the > > preparation callback to be bypassed. To detect possible issues in > > IIUC, we have 2 dedicated flows. > 1 kvm_gmem_get_pfn() or kvm_gmem_allocate() > a. kvm_gmem_get_folio() > b. gmem_prepare() for RMP > > 2 in-place encryption or whatever > a. kvm_gmem_get_folio(FGP_CREAT_ONLY) > b. in-place encryption > c. gmem_prepare() for RMP > > Could we move gmem_prepare() out of kvm_gmem_get_folio(), then we could > have straightforward flow for each case, and don't have to have an > argument to pospone gmem_prepare(). There are 3 flows as you note above - kvm_gmem_get_pfn() and kvm_gmem_allocate() are different paths but they all need to call the prepare hook. It is a tempting idea to pull kvm_gmem_prepare_folio() to the two functions (get_pfn and allocate) but the resulting code is really ugly due to folio_unlock/folio_put. > > -static struct folio *kvm_gmem_get_folio(struct inode *inode, pgoff_t index) > > +#ifdef CONFIG_HAVE_KVM_GMEM_PREPARE > > +bool __weak kvm_arch_gmem_prepare_needed(struct kvm *kvm) > > +{ > > + return false; > > +} > > +#endif > > In which case HAVE_KVM_GMEM_PREPARE is selected but > gmem_prepare_needed() is never implemented? Then all gmem_prepare stuff > are actually dead code. Maybe we don't need this weak stub? It's not needed indeed. > > + if (prepare) { > > + int r = kvm_gmem_prepare_folio(inode, index, folio); > > + if (r < 0) { > > + folio_unlock(folio); > > + folio_put(folio); > > + return ERR_PTR(r); > > + } > > + } > > + > > Do we still need to prepare the page if it is hwpoisoned? I see the > hwpoisoned check is outside, in kvm_gmem_get_pfn(). Yep, it can be moved here. Paolo